• No results found

Having access to the DOM through JavaScript can be used to provide rich user experience when creating dynamic webpages. So far, all you’ve done is obtain references to the elements, which is not particularly useful by itself. The purpose of retrieving elements from the DOM is to be able to do something with them. In this section, you look at how to manipulate the DOM by using JavaScript code to add and remove items.

After you have a reference to a container element, you can add child elements to it dynamically. You can remove elements from it or simply hide elements. When you remove an element from the DOM, it is gone. So if you want to make something invisible to the user but

ptg14200515 be able to use it again later, you can simply hide it by using the appropriate CSS rather than

remove it. Here’s an example:

var element = document.getElementById("innerDiv");

alert(element.innerHTML);

document.removeChild(element);

var afterRemove = document.getElementById("innerDiv");

alert(afterRemove);

The first alert properly shows the innerHTML property of the innerDiv, but the code never reaches the second alert. Instead, the getElementById method throws an error because the element id specified no longer exists in the document.

Be aware of various methods when it comes to adding elements to and removing them from the DOM.

The first method to look at is document.createElement. You use this method of the document object to create a new HTML element. The method receives a single parameter—

the element name of the element you want to create. The following code creates a new

<article> element to use in your page:

var element = document.createElement("article");

element.innerText = "My new <article> element";

This new <article> element isn’t visible to anyone at this point; it merely exists in the DOM for use within your page. Because you don’t have much need to create elements but then not use them, next look at the methods available to get your new <article> element into your page. The first of these methods is appendChild. You use this method to add a new HTML element to the collection of child elements belonging to the calling container. The node is added to the end of the list of children the parent node already contains. The appendChild method exists on the document object as well as on other HTML container elements. It returns a reference to the newly added node. This example appends a new <article> element to the outerDiv:

var outerDiv = document.getElementById("outerDiv");

var element = document.createElement("article");

element.innerText = "My new <article> element";

outerDiv.appendChild(element);

Like most of the other methods explained in this section, the appendChild method returns a reference to the new element appended to the child elements. This is a good way to ensure that you always have a reference to an element for future use, especially when deleting ele-ments. It also enables you to simplify or restructure the code. The following code achieves the same result:

var element = document.getElementById("outerDiv").appendChild(document.

createElement("article"));

element.innerText = "My new <article> element";

ptg14200515 Figure 1-18 shows the output of this code.

FIGURE 1-18 A new <article> element appended to the bottom of the page

You can see that the <article> element was put in at the end of your page. The

appendChild method always adds the new element to the end of the parent element’s child node list. To insert the new <article> element somewhere more precise, the insertBefore method could be more suitable. This method takes two parameters: the new element itself, and the node before which you want to append the new element. For example, to insert your new article before the innerDiv element, you could write the following code:

var element = document.getElementById("outerDiv").insertBefore(

document.createElement("article"), document.getElementById("innerDiv"));

element.innerText = "My new <article> element";

This example uses the getElementById method to get a reference to the node before which you wanted to insert your <article> element in the DOM. You can use other tools to make this code simpler in some cases, depending on the document’s structure. Each element or node has the properties listed in Table 1-3 to help get references to the more common nodes when working with the DOM.

ptg14200515

TABLE 1-3 Properties available on a DOM element

Property Description

childNodes A collection of all child nodes of the parent element.

firstChild A reference to the very first child node in the list of child nodes of the parent node.

lastChild A reference to the very last child node in the list of the child nodes of the parent node.

hasChildNodes A useful property that returns true if the parent element has any child nodes at all.

A good practice is to check this property before accessing other properties, such as firstChild or lastChild.

For an example of these properties, you can change the preceding code to insert your

<article> element as the first element in the innerDiv element:

var inner = document.getElementById("innerDiv");

var element = inner.insertBefore(document.createElement("article"),inner.firstChild);

element.innerText = "My new <article> element";

This code produces the output shown in Figure 1-19.

FIGURE 1-19 The new <article> element inserted as the first child of a <div> element

Your <article> element is now positioned as the first child element of the innerDiv element. Experiment with the other properties to become familiar with how they behave.

Every element that can have child elements supports all this functionality; however, if you try to insert elements into a node that doesn’t support child nodes—such as an <img>, for example—the interpreter throws a run-time error.

ptg14200515 Just as you can add new elements to the DOM through code, you also can remove

ele-ments from the DOM using code. In this section you look at the methods available to do just this, named removeChild and removeNode.

The removeChild method removes a child node from the calling container. This method exists on the document object as well as other HTML container elements. The removeChild method returns a reference to the removed node. This is especially handy if you plan to return that node to the DOM—perhaps in response to some other user interaction with the page. Remember, however, that if you don’t keep the returned reference to the removed node, you have no way to add the element back in without completely re-creating it. The following example removes the first <p> element from your innerDiv element:

var innerDiv = document.getElementById("innerDiv");

var p = innerDiv.removeChild(document.getElementById("P1"));

This code provides the output in Figure 1-20. You can see that the first <p> element has been removed. Because you captured the removed element into the variable p, you could use it later if you wanted to put the <p> element somewhere else.

FIGURE 1-20 Removal of the first <p> element by the removeChild method

Another useful method for removing nodes or elements is removeNode, which takes one Boolean parameter. Setting the parameter as true tells the method to do a deep removal, which means that all children are also removed. The following code demonstrates this:

var innerDiv = document.getElementById("innerDiv");

innerDiv.removeNode(true);

ptg14200515 Figure 1-21 shows that when this code is run in the browser, the innerDiv element has been

removed.

FIGURE 1-21 Using the removeNode method to remove the <div> node

Now, suppose that you want to change the content of the page more dramatically—per-haps even by rewriting all the HTML content. This is completely possible with the techniques you have seen so far, but you haven’t tried some methods yet: replaceNode and replaceChild.

These two methods operate in the same way as removeNode and removeChild in terms of the parameters they take and which elements they affect. The difference, however, is that you can replace the target element with a completely new element. The following code converts all your inner paragraphs to anchor elements and adds line breaks, because you don’t get those automatically as you do from the <p> element:

var innerDiv = document.getElementById("innerDiv");

var newDiv = document.createElement("div");

for (var i = 0; i < innerDiv.childNodes.length; i++) {

var anchor = newDiv.appendChild(document.createElement("a"));

anchor.setAttribute("href", "http://www.bing.ca");

anchor.text = innerDiv.childNodes[i].textContent;

newDiv.appendChild(document.createElement("br"));

}

innerDiv.replaceNode(newDiv);

This code produces the browser output as shown in Figure 1-22.

ptg14200515

FIGURE 1-22 Converting all the <p> elements to <a> elements

All your plain-text paragraphs now display as hyperlinks. Your original innerDiv element is gone and no longer in the DOM. Your only reference to it is within the JavaScript code. You would need to hang on to that reference if you intended to swap it back into the DOM later.

Further, because the code didn’t assign the new <div> element a unique id, the only way to get a reference to it in the DOM is through your existing code reference. For this reason, a recommended practice is to always give your new elements a unique id. If the JavaScript variables go out of scope before you insert them into the document, you lose the references to your elements completely.

In this section, you saw how to access HTML elements by using JavaScript to manipulate the DOM in the browser. You now can retrieve references to the elements or nodes that make up your HTML document as well as modify, add, and remove elements in the HTML document.

Next, you look at implementing media controls into your pages.