JavaScript – Intermediate

ipivanov No Comments JavaScript 61

The DOM

The Document Object Model is a way to manipulate the structure and style of an HTML page. It represents the internals of the page as the browser sees it, and allows the developer to alter it with JavaScript.

Trees and Branches

HTML is an XML-like structure in that the elements form a structure of parents’ nodes with children, like the branches of a tree. There is one root element (html) with branches like head and body, each with their own branches. For this reason, the DOM is also called the DOM tree.

Modifying the DOM, by picking an element and changing something about it, is something done often in JavaScript. To access the DOM from JavaScript, the document object is used. It’s provided by the browser and allows code on the page to interact with the content.

Getting an Element

The first thing to know is how to get an element. There are a number of ways of doing it, and browsers support different ones. Starting with the best supported we’ll move through to the latest, and most useful, versions.

By ID

document.getElementById is a method for getting hold of an element – unsurprisingly – by its ID.


var pageHeader = document.getElementById('page-header');

The pageHeader element can then be manipulated – its size and color can be changed, and other code can be declared to handle the element being clicked on or hovered over. It’s supported in pretty much all the browsers you need to worry about.

By Tag Name

document.getElementsByTagName works in much the same way as getElementById, except that it takes a tag name (a, ul, li, etc) instead of an ID and returns a NodeList, which is essentially an array of the DOM Elements.

By Class Name

document.getElementsByClassName returns the same kind of NodeList as getElementsByTagName, except that you pass a class name to be matched, not a tag name.

By CSS Selector

A couple of new methods are available in modern browsers that make selecting elements easier by allowing the use of CSS selectors. They aredocument.querySelector and document.querySelectorAll.


var pageHeader = document.querySelector('#header');
var buttons = document.querySelectorAll(.btn);

querySelector, like getElementById, returns only one element whereas querySelectorAll returns a NodeList. If multiple elements match the selector you pass to querySelector, only the first will be returned.

Events and Callbacks

In the browser most code is event-driven and writing interactive applications in JavaScript is often about waiting for and reacting to events, to alter the behavior of the browser in some way. Events occur when the page loads, when user interacts (clicks, hovers, changes) and a myriad of other times, and can be triggered manually too.

To react to an event you listen for it and supply a function which will be called by the browser when the event occurs. This function is known as a callback.

Here’s a group of the things needed to listen for an event; the callback function, an element and the call to listen for an event:


var handleClick = function (event) {
    // do something!
};
var button = document.querySelector('#big-button');
button.addEventListener('click', handleClick);

addEventListener is a method found on all DOM elements. Here it’s being called on an element saved in the button variable. The first argument is a string – the name of the event to listen for. Here’s it’sclick – that’s a click of the mouse or a tap of the finger. The second is the callback function – here it’shandleClick.

Data about a particular event is passed to the event callback. Take a look at handleClick, declared above. You can see its argument: event – it’s an object whose properties describe what occurred.

Here’s an example event you might see into a click event callback like handleClick. There are lots of properties giving you an idea of where the event occurred on the page (like pageX and offsetY) – these are slightly different because they depend on the reference point used to measure from. You can also see the target which is a reference to the node that was clicked.


{
    offsetX: 74,
    offsetY: 10,
    pageX: 154,
    pageY: 576,
    screenX: 154,
    screenY: 489,
    target: h2,
    timeStamp: 1363131952985,
    type: "click",
    x: 154,
    y: 395
}

AJAX

In the early years of the web things were simple – a page was text, perhaps with styling, and it contained links to other pages. To get new content you moved from one page to the next. But as developers got more ambitious with the web, attempting to build interactive (“native-like” applications), it was obvious that there needed to be a way to load new content into a page without a full reload.

To retrieve new content for a page, like new articles on an infinite-scroll site or to notify you of new emails, a tool called an XML HTTP Request (XHR) is used. Web apps that do this are also called AJAX apps, AJAX standing for Asynchronous JavaScript and XML.

Almost all sites that pull in new content without a page reload (like Facebook, Gmail, Google Maps etc) use this same technique. In fact, it was Microsoft developing Outlook Web Access who originally created the XMLHttpRequest.

XML HTTP Request

So what does an XMLHttpRequest look like?


var req = new XMLHttpRequest();
req.onload = function (event) { . . . };
req.open('get', 'some-file.txt', true);
req.send();

The first thing to do is create a new XMLHttpRequest request, using the new keyword, and callingXMLHttpRequest like a function.

Then we specify a callback function, to be called when the data is loaded. It is passed information about the event as its first argument.

Then we specify how to get the data we want, using req.open. The first argument is the HTTP method (GET, POST, PUT etc). Next is the URL to fetch from – this is similar to the href attribute of a link.

The third is a boolean specifying whether the request is asynchronous – here we have it true, so the XMLHttpRequest is fired off and then code execution continues until a response from the server causes the onload callback to be fired.

The asynchronous parameter defaults to false – if it’s false, execution of the code will pause at this line until the data is retrieved and the request is called synchronous. Synchronous XMLHttpRequests are not used often as a request to a server can, potentially, take an eternity. Which is a long time for the browser to be doing nothing.

On the last line we tell the browser to fire off the request for data.

AJAX and Libraries

The AJAX technique has been developed to the point now where single-page apps are possible – one main request loads JavaScript code which then loads, asynchronously, other content from the server. Whole libraries and frameworks have been built to help do so, and we’ll take a look at them later.

JSON

JavaScript Object Notation is not JavaScript. Officially it’s a totally different language with its own spec, but it’s such an important part of JavaScript development that it’s important to cover.

JSON is a set of text formatting rules for storing and transferring data in a machine and human readable way. It looks a lot like the object literal syntax of JavaScript, and it is from there JSON originates.

Here’s some JSON:


{ "name": "Yoda", age: 894, "lightsaber" : { "color": "green" } }

Like in JavaScript, the brace notation is used.

JSON is used to transfer information – between your browser to a server, or saved in text files for retrieval later – because it’s simply text. That means you can’t store complex data like a function, but you can store arrays, objects containing simple data, strings and numbers.

Using JSON

Data is either converted to or from JSON, using methods called stringify and parse respectively. JSON is an object available in pretty much all modern browsers but there are ways of adding to a browser that doesn’t have it.


var jsonString = JSON.stringify({
    make: "McLaren",
    model: "MP4-12C",
    miles: 5023
});

JSON.stringify converts an object into a JSON string. In this example, jsonString becomes {"make": "McLaren", "model": "MP4-12C", "miles": 5023 }.


var car = JSON.parse(jsonString);

The string can then be converted back to a JavaScript object using JSON.parse. car is now usable as a normal JavaScript object, so you can set its properties:


car.model = "P1";

Scope

Scope is the term used to mean variable visibility — a variable’s scope is the part of your code that can access and modify that variable. JavaScript has function scope — but what does that mean and how is it different to other languages?

Scope is, in many programming languages, dictated by the block in which the variable was declared. A block, in C-like languages, is anything between two curly braces, or indentation in a language like Python. For example, the b variable below is not available outside the curly braces in which it was declared:


var a = 10;

if (a > 5) {
    var b = 5;
}

var c = a + b; // Wouldn't work!

Function scope

JavaScript does things a little differently. It uses function scope. This means that variables are not visible outside of the function in which they were declared. If they are not declared inside a function then they are available globally.

The example below demonstrates that a variable is only visible inside the function in which it was declared. The doSomething function is the variable a’s scope.


var doSomething = function () {
    var a = 10;
};

doSomething();

console.log(a); // a is undefined

Comparing this to the block scope example above, you can see that, in JavaScript, b is available:


var a = 10;

if (a > 5) {
    var b = 5;
}

var c = a + b; // c is 15

Child scopes

Variables are available in child scopes of their own scope. For example, doSomethingElse is a child of doSomething, so a is visible insidedoSomethingElse.


var doSomething = function () {
    var a = 10;
var doSomethingElse = function () {
    console.log(a); // a is 10
};
doSomethingElse();
};

doSomething();

Functional scope is a very powerful tool for creating elegant code, as we’ll see, but it can take some time to get your head around.

 

Leave a Reply Text

Leave a Reply