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.
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>
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");
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>
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>
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.
You can create and insert new element in three-step.
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>
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);
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);
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));
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"
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 );