<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="js/script.js"></script>
</head>
<body>
<h1 id="title">Lecture 54</h1>
<p>
Say hello to
<input id="name" type="text">
<button onclick="sayHello();">
Say it!
</button>
</p>
<div id="content"></div>
</body>
</html>
- fetch HTML element
document.getElementById( "title" ) // <h1 id="title">Lecture 53</h1>
- PS. Be sure that "title" element exists in rendering HTML page before
document.getElementById
invoking, or it will result innull
.- So javascript code is always best not to keep it in the head, but actually place it at the very end.
- PS. Be sure that "title" element exists in rendering HTML page before
- Change HTML structure
function sayHello() { var name = document.getElementById( "name" ).value; var message = "Hello " + name + "!"; document.getElementById( "content" ).textContent = message; }
- How can I change "content" text to h2 headering ?
var message = "<h2>Hello " + name + "!</h2>";
- Adding h2 tag literally does not work, it is just text, not really something that the browser should render.
- How to solve it ?
// document.getElementById( "content" ).textContent = message; document.getElementById( "content" ).innerHTML = message; // or append to existing ones document.getElementById( "content" ).innerHTML += message;
- but, altering innerHTML will destory all EventListener on that dom element. To preserve existing EventListener, use
insertAdjacentHTML
instead.targetElem.insertAdjacentHTML('beforeend', html );
- How can I change "content" text to h2 headering ?
- QuerySelector
- the way you select things using CSS
document.querySelector( "#title" ).textContent = "XXX"; // document.querySelector( "h1" ) // will return the first matching element // document.queryAllSelector( "h1" ) // a list of all matching element
- In Lecture 53, we've already seen a simple example of how to bind an event handler to a particular element.
<button onclick="sayHello();">
- Let's explore now couple of different ways that you can actually assign event handlers to elements.
- What is event handler ?
- Well event handlers are basically functions that you bind using specific methods to certain events that happen in the browser.
- Those events might be triggered by just a lifecycle. Meaning something like the page loaded. Or it could be triggered by user interaction, like a user typed a character or user clipped something.
- One of the most simplest ways to assign an event handler to a particular element is to just use the on
<something>
attribute on that element.- onblur(lose focus), onclick, ondblclick, onfocus, onkeydown, onkeypress, onkeyup, onmousedown,
- This method comes with some side effects.
- you kind of have to dirty up your HTML with these on-events, we may hope the HTML is just for content.
this
insayHello
function is pointing to window object becausesayHello
function is defined in Global scope.
- UnObtrusive Event Binding
- The HTML does not need to know anything about your JavaScript.
function sayHello() { ... } document.querySelector("button").addEventListener( "click", sayHello );
- Now
this
insayHello
function is pointing to the containing object, the button element.
- Another similar way
document.querySelector("button").onclick = sayHello ;
- DOMContentLoaded event
- a life cycle event of the page
- that will let us actually assign the events to the elements of the page once they load, but before anything else loads. Before any images load, before any CSS loads, and so forth.
- And since we are going to be listening for that event, we no longer need to provide this script at the bottom of the page. We can actually cut this script out of here, and place it very easily in the head.
document.addEventListener("DOMContentLoaded", ... );
- What we want to do is we want to assign a function, with parameter
event
, and every event handler function gets this event object.document.addEventListener("DOMContentLoaded", function (event) { ... } );
- and inside this function, we can now start assigning different events.
document.addEventListener("DOMContentLoaded", function (event) { function sayHello (event) { ... } // Unobtrusive event binding document.querySelector("button").addEventListener("click", sayHello); } );
- This function will get executed when this Event files called, dom content loaded and that will happen before any images, or any CSS, or any other script is loaded.
- When mouse-left clicking the button, the object that event is
MouseEvent
.- PS. you would not get event if you bind the function via
on-event
attributes in HTML.
- PS. you would not get event if you bind the function via
- Asynchronous Javascript and XML
- While Ajax started with XML, very few apps use it nowadays
- Plain text (at time as html) and JSON is used instead
- Why does Ajax exist to begin with ?
- Faster response. Less bandwidth, nicer experience for user
ajax-utils.js
(function (global) {
// Set up a namespace for our utility
var ajaxUtils = {};
// Returns an HTTP request object
function getRequestObject() {
if (global.XMLHttpRequest) {
return (new XMLHttpRequest());
}
else if (global.ActiveXObject) {
// For very old IE browsers (optional)
return (new ActiveXObject("Microsoft.XMLHTTP"));
}
else {
global.alert("Ajax is not supported!");
return(null);
}
}
// Makes an Ajax GET request to 'requestUrl'
ajaxUtils.sendGetRequest =
function(requestUrl, responseHandler) {
var request = getRequestObject();
request.onreadystatechange =
function() {
handleResponse(request, responseHandler);
};
// true: async, false: sync
request.open("GET", requestUrl, true);
request.send(null); // for POST only
};
// Only calls user provided 'responseHandler'
// function if response is ready
// and not an error
function handleResponse(request,
responseHandler) {
if ((request.readyState == 4) &&
(request.status == 200)) {
responseHandler(request);
}
}
// Expose utility to the global object
// just like jQuery uses `$`, we use `$` as well.
global.$ajaxUtils = ajaxUtils;
})(window);
- Sending Ajax request
// Call server to get the name $ajaxUtils .sendGetRequest("data/name.txt", function (request) { var name = request.responseText; document.querySelector("#content") .innerHTML = "<h2>Hello " + name + "!</h2>"; });
- converts from json string to object
var obj = JSON.parse( jsonString ) ;
- converts from object to json string
var str = JSON.stringify( obj ) ;
ajax-utils.js improved by JSON support
(function (global) {
// Set up a namespace for our utility
var ajaxUtils = {};
// Returns an HTTP request object
function getRequestObject() {
if (global.XMLHttpRequest) {
return (new XMLHttpRequest());
}
else if (global.ActiveXObject) {
// For very old IE browsers (optional)
return (new ActiveXObject("Microsoft.XMLHTTP"));
}
else {
global.alert("Ajax is not supported!");
return(null);
}
}
// Makes an Ajax GET request to 'requestUrl'
ajaxUtils.sendGetRequest =
function(requestUrl, responseHandler, isJsonResponse) {
var request = getRequestObject();
request.onreadystatechange =
function() {
handleResponse(request,
responseHandler,
isJsonResponse);
};
request.open("GET", requestUrl, true);
request.send(null); // for POST only
};
// Only calls user provided 'responseHandler'
// function if response is ready
// and not an error
function handleResponse(request,
responseHandler,
isJsonResponse) {
if ((request.readyState == 4) &&
(request.status == 200)) {
// Default to isJsonResponse = true
if (isJsonResponse == undefined) {
isJsonResponse = true;
}
if (isJsonResponse) {
responseHandler(JSON.parse(request.responseText));
}
else {
responseHandler(request.responseText);
}
}
}
// Expose utility to the global object
global.$ajaxUtils = ajaxUtils;
})(window);
- The name of the jQuery function is
$
.- example
$( // Same as document.addEventListener("DOMContentLoaded"... function () { // Same as document.querySelector("#navbarToggle").addEventListener("blur",... $("#navbarToggle").blur(function (event) { var screenWidth = window.innerWidth; // browse window, not entire monitor screen if (screenWidth < 768) { $("#collapsable-nav").collapse('hide'); // collapse function is from bootstrap } }); // In Firefox and Safari, the click event doesn't retain the focus // on the clicked button. Therefore, the blur event will not fire on // user clicking somewhere else in the page and the blur event handler // which is set up above will not be called. // Refer to issue #28 in the repo. // Solution: force focus on the element that the click event fired on $("#navbarToggle").click(function (event) { $(event.target).focus(); }); });
// Convenience function for inserting innerHTML for 'select'
var insertHtml = function (selector, html) {
var targetElem = document.querySelector(selector);
targetElem.innerHTML = html;
};
// Show loading icon inside element identified by 'selector'.
var showLoading = function (selector) {
var html = "<div class='text-center'>";
html += "<img src='images/ajax-loader.gif'></div>";
insertHtml(selector, html);
};
-
where to get that
ajax-loader.gif
? -
Issue Ajax request
// On first load, show home view showLoading("#main-content"); $ajaxUtils.sendGetRequest( homeHtml, function (responseText) { document.querySelector("#main-content") .innerHTML = responseText; }, false); });
<li id="navHomeButton" class="visible-xs active">
<a href="index.html">
<span class="glyphicon glyphicon-home"></span> Home</a>
</li>
// Remove the class 'active' from home and switch to Menu button
var switchMenuToActive = function () {
// Remove 'active' from home button
var classes = document.querySelector("#navHomeButton").className;
classes = classes.replace(new RegExp("active", "g"), "");
document.querySelector("#navHomeButton").className = classes;
// Add 'active' to menu button if not already there
classes = document.querySelector("#navMenuButton").className;
if (classes.indexOf("active") == -1) {
classes += " active";
document.querySelector("#navMenuButton").className = classes;
}
};