Moving Around the DOM

We can move around inside the DOM(tree structure of the DOM), parse the layout of HTML document and we can see how elements relate to each other.

Instead of directly accessing the middle of the document by ID, class, tag name, or by specific position in the NodeList, we can navigate up and travel around the DOM.

The following are the five new methods to travel around the DOM.

  • parentNode
  • previousSibling
  • nextSibling
  • firstChild
  • lastChild

You can get the children of an element node, its parent (or parents), and they all have parents.

Consider the html code below.

<ul id="nav">
    <li><a href="/" id="home">Home</a></li>
    <li><a href="/about" id="about">About Us</a></li>
    <li><a href="/contact" id="contact">Contact Us</a></li>
</ul>
Targeting a parentNode

The below code gets the parent element for the target node and adds a class of "active" to it.

// target the "about" link and apply a class to its parent list item

document.getElementById("about"). parentNode .setAttribute("class", "active");
Adding a Class to Previous and Next Sibling Nodes

Apart from moving in a parent-child relationship (up and down), you can also move side to side in the DOM and target nodes that sit next to a target node. These are called siblings, and you can target them using the methods previousSibling and nextSibling.

// get "about" parent, then its previous sibling and apply a class
document.getElementById("about").parentNode. previousSibling .setAttribute "class", "previous");

// get "about" parent, then its next sibling and apply a class
document.getElementById("about").parentNode. nextSibling .setAttribute("class", "next");

The above code will generate HTML After Adding Classes

<ul id="nav">
    <li class=" previous"><a href="/" id="home">Home</a></li>
    <li class=" active"><a href="/about" id="about">About Us</a></li>
    <li class=" next"><a href="/contact" id="contact">Contact Us</a></li>
</ul>
Accessing First and Last Child

You can directly move straight to the first or last item in a NodeList with JavaScript to get node information.

Adding a Class to the First and Last Items in Our Nav

// travel to the first node and add the class
document.getElementById("nav"). firstChild .setAttribute("class", "first");

// travel to the last node and add a class
document.getElementById("nav"). lastChild .setAttribute("class", "last");

The above code will generate HTML After Adding Classes

<ul id="nav">
    <li class="first"><a href="/" id="home">Home</a></li>
    <li><a href="/about" id="about">About Us</a></li>
    <li class="last"><a href="/contact" id="contact">Contact Us</a></li>
</ul>
Dynamically Adding and Removing Nodes from the DOM

With Javascript you can dynamically insert nodes into the DOM, create new elements, fill them with content, and drop them into the document somewhere.

The following are the methods to do this. The first three methods will insert new elements into the DOM.

  • createElement()
  • createTextNode()
  • appendChild()
  • removeChild()
Adding Elements to the DOM

You can create and insert new element in three-step.

  1. Create the element.
  2. Fill it with content (or leave it blank).
  3. Put in the DOM.
  1. To create the element use the createElement([tagname]) method. It takes one argument, which is the tag name of the element you want to create. It doesn't actually exist until we put it in the DOM.
  2. To add content to your element use the createTextNode() method. It takes one argument, which is content(a string of text) that will be inserted into the element.
  3. To insert your new element pick a point in the DOM and add using appendChild() method. It takes one argument, which is the completed element you want to insert.

The new element will be added in the below html.

<body>
    <div id="target-area">
        <p id="tagline">Hello World!</p>
    </div>
</body>

HTML Example to Create a New Element

// store the target area to a variable to keep things neat
var targetArea = document.getElementById("target-area");

// create our <p> element
var p = document. createElement ("p");

// create a text node inside the <p>, note that we're using a variable "p" here
var snippet = p. createTextNode ("this was a generated paragraph");

// insert our generated paragraph into the DOM
targetArea.appendChild (snippet);

The generated HTML will have the new element inserted into the DOM

<body>
    <div id="target-area">
        <p id="tagline">Hello World!</p>
        <p>this was a generated paragraph</p>
    </div>
</body>
Removing Elements from the DOM

You can remove elements from the document with the removeChild() method.

<body>
    <div id="target-area">
        <p id="tagline">Hello World!</p>
    </div>
</body>

In the above HTML, to remove the paragraph tagline, navigate to its parent and remove the child with the removeChild() method.

JavaScript for Removing an Element from the DOM

// store the target area to a variable to keep things neat
var targetArea = document.getElementById("target-area");

// store the tagline in a variable as well
var tagline = document.getElementById("tagline");

// remove it from the DOM
targetArea.removeChild (tagline);
replaceChild()

The replaceChild() method removes a node and puts another one in its place.

<body>
    <p class="opener">first paragraph</p>
    <p id="closer">final</p>
    <!-- and that's about it -->
</body>

Create a new node and replace the second paragraph with the ID "closer".

//new element
var para = document. createElement ("p");

// create a text node inside the <p>, note that we're using a variable "p" here
var snippet = p. createTextNode ("this was a generated paragraph");
var p = document.getElementsByTagName('p')[1];
p
<p id="closer">

Replace this paragraph with the new element we created.

var replaced = document.body.replaceChild(para, p);

Just like removeChild(), replaceChild() returns a reference to the node that is now out of the tree.

replaced

<p id="closer">

Now the body looks like:

<body>
    <p class="opener">first paragraph</p>
    <p><em>second</em> paragraph</p>
    <!-- and that's about it -->
</body>

A quick way to wipe out all of the content of a subtree is to set the innerHTML to a blank string. This will remove all of the children of the BODY.

document.body.innerHTML = '';

Testing:

document.body.firstChild

null

To remove all content with DOM-only is to go over all of the child nodes and remove each one individually.

Below function removes all nodes from a given start node.

function removeAll(n) {
    while (n.firstChild) {
        n.removeChild(n.firstChild);
    }
}

To delete all BODY children and leave the page with an empty <body></body>.

removeAll(document.body);
cloneNode Copying Content

A node can be in only one place in the DOM tree at any given time. Another way to create nodes is by copying (or cloning) existing node with or without its descendants, using cloneNode() method.

Node.cloneNode() takes a boolean parameter (true = deep copy with all the children(the whole branch of the DOM tree), false = shallow copy, only this node). Pass in true if you want to duplicate the node and its descendants (the whole branch of the DOM tree).

Otherwise, pass in false, and JavaScript will duplicate the element as if it were empty.

<todo -change example based on existing html>

var myUL = document.getElementsByTagName("ul")[0];

myUL.parentNode.appendChild(myUL.cloneNode(true));
Note
Only Node.cloneNode() gives you the option to do a deep or shallow copy, Node.appendChild(), Node.insertBefore(), Node.replaceChild(), and Node.removeChild() do not. Those four manipulate a node with its descendants, no matter what.
cloneNode()

Another way to create nodes is by copying (or cloning) existing ones. The method cloneNode() does this and accepts a boolean parameter (true = deep copy with all the children, false = shallow copy, only this node). Let's test the method.

Getting a reference to the element you want to clone:

var el = document.getElementsByTagName('p')[1];

Now el refers to the second paragraph on the page that looks like this:

<p><em>second</em> paragraph</p>

Let's create a shallow clone of el and append it to the body:

document.body.appendChild(el.cloneNode(false))

You won't see a difference on the page, because the shallow copy only copied the P node, without any children. This means that the text inside the paragraph (which is a text node child) was not cloned. The line above would be equivalent to:

document.body.appendChild(document.createElement('p'));

Now if you create a deep copy, the whole DOM subtree starting from P will be copied, and this includes text nodes and the EM element.

document.body.appendChild(el.cloneNode(true))

You can also copy only the EM if you want:

document.body.appendChild(el.firstChild.cloneNode(true))

<em>

Or only the text node with value "second":

document.body.appendChild(el.firstChild.
firstChild.cloneNode(false))
"second"

insertBefore()

The insertBefore() method is same as appendChild()(adds new children at the end of the selected element), but accepts an extra parameter, specifying before which element to insert the new node.

The following code will insert a text node at the end of the body.

document.body.appendChild(document.createTextNode('boo!'));

The below code will add the text node as the first child of the body.

document.body.insertBefore(
    document.createTextNode('boo!'),
    document.body.firstChild
);
Related Tutorial
Follow Us
https://www.facebook.com/Rookie-Nerd-638990322793530 https://twitter.com/RookieNerdTutor https://plus.google.com/b/117136517396468545840 #
Contents +