MOZILLA'S DOM INSPECTOR

Course- Javascript >

One of the easiest ways to view node information is by using the DOM Inspector available for Mozilla Firefox. If you use Firefox, you may find the DOM Inspector already installed, though since Firefox 3 it’s been available as a separate add-on. You can download it at https://addons.mozilla.org/en-US/firefox/addon/dom-inspector-6622/.

Once installed, you can open the DOM Inspector for any page you have loaded in the browser by pressing Ctrl+Shft+I. The window that opens is shown in snapshot, displaying the DOM representation of the web page above. selecting elements with getElementsByTagname.

JAVASCRIPT MOZILLA'S DOM INSPECTOR

A DOM node is selected from the tree structure in the left-hand display pane, and details about it can be examined in the right-hand pane. As well as the viewer for the DOM tree, other viewers are included for viewing CSS rules, style sheets, computed style, JavaScript objects, and more.

The interface can seem a little daunting at first, but it’s well worth exploring the program’s capabilities.


Creating New Nodes

Adding new nodes to the DOM tree is a two-stage process:

1. First, you create a new node. Once created, the node is initially in a kind of “limbo”; it exists, but it’s not actually located anywhere in the DOM tree, and therefore doesn’t appear on the visible page in the browser window.

2. Next, you add the new node to the tree, in the desired location. At this point it becomes part of the visible page.

Let’s look at some of the methods of the document object that are available for creating nodes.

createElement()

You can call on the createElement() method to create new HTML elements having any of the standard HTML element types—paragraphs, spans, tables, lists, and so on.

Let’s suppose you’ve decided to create a new <div> element for your document. To do so, you simply need to pass the relevant nodeName value—in this case "div"—to the createElement method:

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

The new <div> element now exists, but currently has no contents, no attributes, and no location in the DOM tree. You see how to solve these issues shortly.

createTextNode()

Many of the HTML elements in your page need some content in the form of text. The createTextNode() method takes care of that. It works pretty much like createElement(), except that the argument it accepts is not a nodeName value, but a string containing the desired text content of the element:

var newTextNode = document.createTextNode("Here is some text content.");

As with createElement(), the newly created node is not yet located in the DOM tree; JavaScript has it stored in the newTextNode variable while it waits for you to place it in its required position.

cloneNode()

There’s no point in reinventing the wheel. If you already have a node in your document that’s just like the new one you want to create, you can use cloneNode() to do so.

Unlike createElement() and createTextNode(), cloneNode() takes a single argument—a Boolean value of true or false.

Passing true to the cloneNode() function tells JavaScript that you want to clone not only the node, but all of its child nodes:

var myDiv = document.getElementById("id1");
var newDiv = myDiv.cloneNode(true);                    
                    

In this example, I’ve asked JavaScript to clone the element’s child nodes too; for example, any text that myDiv contained (which would be contained in a child text node of the element) will be faithfully reproduced in the new <div> element.

Had i called

var newDiv = myDiv.cloneNode(false);

then the new <div> element would be identical to the original, except that it would have no child nodes. It would, for instance, have any attributes belonging to the original element (provided that the original node was an element node, of course).

As with new nodes created by createElement() and createTextNode(), the new node created by cloneNode() is initially floating in space; it does not yet have a place in the DOM tree.

You see how to achieve that next.

Manipulating Child Nodes

The new nodes you’ve created aren’t yet of any practical value, as they don’t yet appear anywhere in the DOM. A few methods of the document object are specifically designed for placing nodes in the DOM tree, and they are described in the following sections.

appendChild()

Perhaps the simplest way of all to attach a new node to the DOM is to append it as a child node to a node that already exists somewhere in the document. Doing so is just a matter of locating the required parent node and calling the appendChild() method:

var newText = document.createTextNode("Here is some text content.");
var myDiv = document.getElementById("id1");
myDiv.appendChild(newText);                    
                    

In the preceding code snippet, a new text node has been created and added as a child node to the currently existing <div> element having an id of id1.

Remember that appendChild() always adds a child node after the last child node already present, so the newly appended node becomes the new lastChild of the parent node.

Of course, appendChild() works equally well with all types of nodes, not just text nodes. Suppose you needed to add another

element within the parent <div> element:

 

var newDiv = document.createElement("div");
var myDiv = document.getElementById("id1");
myDiv.appendChild(newDiv);                    
                    

Your originally existing <div> element now contains a further <div> element as its last child; if the parent <div> element already contained some text content in the form of a child text node, then the parent div (as represented in the newly modified DOM, not in the source code) would now have the following form:

<div id="id1">
Original text contained in text node
<div></div>
</div>                   
                    

insertBefore()

Whereas appendChild() always adds a child element to the end of the list of children, with insertBefore() you can specify a child element and insert the new node immediately before it.

The method takes two arguments: the new node, and the child before which it should be placed. Let’s suppose that your page contains the following HTML snippet:

<div id="id1">
<p id="para1">This paragraph contains some text.</p>
<p id="para2">Here's some more text.</p>
</div>                    
                    

To insert a new paragraph between the two that are currently in place, first create the new paragraph:

var newPara = document.createElement("p");

Identify the parent node, and the child node before which you want to make the insertion:

var myDiv = document.getElementById("id1");
var para2 = document.getElementById("para2");

Then pass these two as arguments to insertBefore():

myDiv.insertBefore(newPara, para2);

replaceChild()

You can use replaceChild() when you want to replace a current child node of a specific parent element with another node. The method takes two arguments—a reference to the new child element followed by a reference to the old one.

Try it Yourself: Replacing Child Elements

<!DOCTYPE html>
<html>
<head>
<title>Replace Page Element</title>
</head>
<body>
<div id="id1">
<p id="para1">Welcome to my web page.</p>
<p id="para2">Please take a look around.</p>
<input id="btn" value="Replace Element" type="button" />
</div>
</body>
</html>                    
                    

Suppose that you want to use the DOM to remove the first paragraph in the <div> and replace it instead with an <h2> heading as follows:

<h2>Welcome!</h2>

First create the new node representing the <h2> heading:

var newH2 = document.createElement("h2");

This new element needs to contain a text node for the heading text. You can either create it and add it now, or do it later when you’ve added your new <h2> element to the DOM. Let’s do it now:

var newH2Text = document.createTextNode("Welcome!");
newH2.appendChild(newH2Text);

Now you can swap out the unwanted child node of the <div> element and replace it with the new one:

var myDiv = document.getElementById("id1");
var oldP = document.getElementById("para1");
myDiv.replaceChild(newH2, oldP);                    
                    

Finally, you need to add an onclick event handler to the button element, so that when the button is clicked, your element replacement function is executed. We do that with an anonymous function assigned to the window.onload method:

window.onload = function() {
document.getElementById("btn").onclick = replaceHeading;
}                    
                    

this shows the code for the page with the JavaScript added

The Completed Code to Replace Child Elements

<html>
<head>
<title>Replace Page Element</title>
<script>
function replaceHeading() {
var newH2 = document.createElement("h2");
var newH2Text = document.createTextNode("Welcome!");
newH2.appendChild(newH2Text);
var myDiv = document.getElementById("id1");
var oldP = document.getElementById("para1");
myDiv.replaceChild(newH2, oldP);
}
window.onload = function() {
document.getElementById("btn").onclick = replaceHeading;
}
</script>
</head>
<body>
<div id="id1">
<p id="para1">Welcome to my web page.</p>
<p id="para2">Please take a look around.</p>
<input id="btn" value="Replace Element" type="button" />
</div>
</body>
</html>                    
                    

Create a new HTML file with your editor and insert the code above. On loading the page into your browser, you should see the two single-line paragraphs of text with the button beneath. If all has gone according to plan, clicking the button should swap the first <p> element for your <h2> heading,

On loading the page into your browser, you should see the two single-line paragraphs of text with the button beneath. If all has gone according to plan, clicking the button should swap the first <p> element for your <h2> heading

removeChild()

There is a DOM method specifically provided for removing child nodes from the DOM tree.

Referring once more to below code, if you wanted to remove the <p> element with id="para2" you can just use

<!DOCTYPE html>
<html>
<head>
<title>Replace Page Element</title>
</head>
<body>
<div id="id1">
<p id="para1">Welcome to my web page.</p>
<p id="para2">Please take a look around.</p>
<input id="btn" value="Replace Element" type="button" />
</div>
</body>
</html>                    
                    

var myDiv = document.getElementById("id1");
var myPara = document.getElementById("para2");
myDiv.removeChild(myPara);                    
                    

If you don’t have a handy reference to the element’s parent, just use the parentNode property:

myPara.parentNode.removeChild(myPara);

The return value from the removeChild() method contains a reference to the removed node. If you need to, you can use this to further process the child node that has just been removed:

var removedItem = myDiv.removeChild(myPara);
alert('Item with id ' + removedItem.getAttribute("id") + ' has been
removed.');                    
                    

Editing Element Attributes

In the previous section you saw how to read element attributes using the getAttribute() method.

There is a corresponding method named setAttribute() to allow you to create attributes for element nodes and assign values to those attributes. The method takes two arguments; unsurprisingly, these are the attribute to be added and the value it should have.

In the following example, the title attribute is added to a <p> element and assigned the value “Opening Paragraph”:

var myPara = document.getElementById("para1");
myPara.setAttribute("title", "Opening paragraph");

Setting the value of an attribute that already exists effectively overwrites the value of that attribute. You can use that knowledge to effectively edit existing attribute values:

var myPara = document.getElementById("para1");
myPara.setAttribute("title", "Opening paragraph"); // set 'title'
attribute
myPara.setAttribute("title", "New title"); // overwrite 'title'
attribute                    
                    

Dynamically Loading JavaScript Files

On occasion you’ll want to load JavaScript code on the fly to a page that’s already loaded in the browser. You can use createElement() to dynamically create a new <script> element containing the required code, and then add this element to the page’s DOM:

var scr = document.createElement("script");
scr.setAttribute("src", "newScript.js");
document.head.appendChild(scr);                    
                    

Remember that the appendChild() method places the new child node after the last child currently present, so the new <script> element will go right at the end of the <head> section of the page.

Take note, though, that if you dynamically load JavaScript source files using this method, the JavaScript code contained in those files will not be available to your page until the external file has finished loading.

You would be well advised to have your program check that this is so before attempting to use the additional code.

Nearly all modern browsers implement an onload event when the script has downloaded. This works just like the window.onload event you’ve already met, but instead of firing when the main page has finished loading, it does so when the external resource (in this case a JavaScript source file) is fully downloaded and available for use:

src.onload = function() {
... things to do when new source code is downloaded ...
}                    
                    

Note: This won’t work in older versions of Internet Explorer, but onload has been supported for script elements since IE8. To be sure, you may prefer to use object detection of the resources contained in your newly loaded file instead.

Try it Yourself: A Dynamically Created Menu

In this exercise you’re going to use the techniques learned in this and the previous section to create page menus on the fly.

Our example HTML page has a top-level <h1> heading, followed by a number of short articles each consisting of an <h2> heading followed by some paragraphs of text. This is similar to a format you might see in a blog, a news page, or the output from an RSS reader, among other examples.

What you are going to do is employ DOM methods to automatically generate a menu at the page head, having links that allow the user to jump to any of the articles on the page. The HTML file is shown in below given code. Create your own HTML file based on this script. Feel free to use your own content for the headings and text, so long as the section titles are contained in <h2> elements.

 

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Scripting the DOM</title>
<script src="menu.js"></script>
<script>window.onload = makeMenu;</script>
</head>
<body>
<h1>The Extremadura Region of Western Spain</h1>
<h2>Geography Of The Region</h2>
<p>The autonomous community of Extremadura is in western Spain
alongside the
Portuguese border. It borders the Spanish regions of Castilla y Leon,
Castilla La
Mancha and Andalucía as well as Portugal (to the West). Covering over
40,000 square
kilometers it has two provinces: Cáceres in the North and Badajoz in the
South.</p>
<h2>Where To Stay</h2>
<p>There is a wide range of accommodation throughout Extremadura
including small inns and guest houses ('Hostals') or think about renting a 'casa rural'
(country house)if you are traveling in a group.</p >
<h2>Climate</h2 >
<p >Generally Mediterranean, except for the north, where it is
continental.
Generally known for its extremes, including very hot and dry summers with
frequent
droughts, and its long and mild winters.</ p>
<h2>What To See</h2 >
<p>Extremadura hosts major events all year round including theater,
music,
cinema, literature and folklore. Spectacular venues include castles,
medieval town
squares and historic centers. There are special summer theater festivals
in the
Mérida, Cáceres, Alcántara and Alburquerque.</p>
<h2>Gastronomy</h2& gt;
<p& gt;The quality of Extremaduran food arises from the fine quality of
the local
ingredients. In addition to free-range lamb and beef, fabulous cheeses,
red and
white wines, olive oil, honey and paprika, Extremadura is particularly
renowned for
Iberian ham. The 'pata negra' (blackfoot) pigs are fed on acorns in the
cork-oak
forests, the key to producing the world's best ham and cured sausages. .
</p>
</body>
</html>                    
                    
Page that is to have a dynamically created menu

The first thing to do is make a collection of all the <h2> elements from the page. These will form the items in your menu. For each of these headings make a link to an anchor element that you place right next to the corresponding <h2> element. The menu links will be arranged as links in an unordered list (<ul>) element. This list will be placed in a <div> container that you insert at the page head.

First, get the collection of <h2> elements:

var h2s = document.getElementsByTagName("h2");

You need to create the <div> container to hold your menu; inside that <div>, there’ll be a <ul> list element to contain the menu items:

var menu = document.createElement("div");
var menuUl = document.createElement("ul");
menu.appendChild(menuUl);

Now you can cycle through the collection of <h2> headings:

for(var i = 0; i < h2s.length; i++) {
... do things for each heading ...
}

For each heading you find in the document, you have a number of tasks to perform:

  • Collect the content of the heading’s child text node, which forms the text of the heading:
    var itemText = h2s[i].childNodes[0].nodeValue;
  • Create a new list item (<li>) element for the menu:
    var menuLi = document.createElement("li");
  • Add that <li> element to the menu:
    menuUl.appendChild(menuLi);
  • Each list item must contain a link to an anchor located next to the heading to which the menu item points:
    var menuLiA = document.createElement("a");
    menuLiA = menuLi.appendChild(menuLiA);
  • Set an appropriate href attribute of the link (remember that variable i increments as you count through the headings in the array). These links will have the form
    <a href="#itemX">[Title Text]</a>
    where X is the index number of the menu item:
    menuLiA.setAttribute("href", "#item" + i);
  • Create a matching anchor element just before each <h2> heading. The anchor elements have the form
    <a href="#itemX">
    so you need to add the name attribute, and locate the link just before the associated heading:
var anc = document.createElement("a");
anc.setAttribute("name", "item" + i);
document.body.insertBefore(anc, h2s[i]);                    
                    

When all that has been completed for each <h2> heading, you can add your new menu to the page:

document.body.insertBefore(menu, document.body.firstChild);

The content of the JavaScript source file menu.js is shown in given below code. The code has been incorporated into a function named makeMenu() that is called by the window.onload event handler, building your menu as soon as the page has loaded and the DOM is therefore available.

JavaScript Code for menu.js

function makeMenu() {
// get all the H2 heading elements
var h2s = document.getElementsByTagName("h2");
// create a new page element for the menu
var menu = document.createElement("div");
// create a UL element and append to the menu div
var menuUl = document.createElement("ul");
menu.appendChild(menuUl);
// cycle through h2 headings
for(var i = 0; i < h2s.length; i++) {
// get text node of h2 element
var itemText = h2s[i].childNodes[0].nodeValue;
// add a list item
var menuLi = document.createElement("li");
// add it to the menu list
menuUl.appendChild(menuLi);
// the list item contains a link
var menuLiA = document.createElement("a");
menuLiA = menuLi.appendChild(menuLiA);
// set the href of the link
menuLiA.setAttribute("href", "#item" + i);
// set the text of the link
var menuText = document.createTextNode(itemText);
menuLiA.appendChild(menuText);
// create matching anchor element
var anc = document.createElement("a");
anc.setAttribute("name", "item" + i);
// add anchor before the heading
document.body.insertBefore(anc, h2s[i]);
}
// add menu to the top of the page
document.body.insertBefore(menu, document.body.firstChild);
}                    
                    

This Snapshot first shows the script in action.

By examining the modified DOM using your browser tools, you can see the additional DOM elements added to the page to form the menu and the anchors.

The automatic menu script in action

This Snapshot shows how this is displayed in Google Chromium’s Developer Tools, highlighting the additional elements.

The additional DOM elements