Now that we've covered some solid ground on HTML DOM basics we can now move on to explore its real potential. In this chapter we will cover only part of this potential by introducing you to some of the most common DOM properties and methods used on HTML elements - part of the rest of potential lying in HTML events which is just another whole world to discover!

Getting and setting content

Amongst the most common things done using the HTML DOM is retrieving and setting the content of an HTML element. The innerHTML and innerText properties are the players in this game. Both the properties are of type string.

The innerHTML property holds the HTML content of a given element.

The innerText property holds the text content of a given element with HTML tags stripped off.

Before we see both of these in action let's first consider the following HTML code which we will use for the rest of the chapter.

<!DOCTYPE html>
<html>
    <body>
        <h1>A heading</h1>
        <p>A paragraph</p>
    </body>
</html>

It all works best when you try it yourself so go on and make this HTML page in your computer and do the tasks as shown.

innerHTML

If we want to get the HTML content of the the body element we'll use the innerHTML property. We'll obviously first have to select the element:

document.querySelector("body").innerHTML; /* returns
"
    <h1>A heading</h1>
    <p>A paragraph</p>

"
The innerHTML property returns the actual HTML content of a given element i.e all spaces and line-breaks are preserved. Check out the HTML example above and see what is between the starting and ending body tags. Try compressing the content inside the body tag and then see what you get returned by the innerHTML property!

If we want to set the HTML content of the body element we'll again use the innerHTML property but this time assigning it a value:

document.querySelector("body").innerHTML = "<p>Changed content</p>";

Now the HTML body would have only a p element with text Changed content. Go on and try this code in your HTML page! You'll notice the previous heading and paragraph gone!

innerText

If we want to get the text content of the the body element we'll use the innerText property:

document.querySelector("body").innerText; /* returns
"A heading
A paragraph"
The innerText property returns only the text content in an element. All spaces are removed however line-breaks between the text nodes are preserved.

If we want to set the text content of the body element we'll again use the innerText property but this time assigning it a value:

document.querySelector("body").innerText = "Changed content";

Now the HTML body would have only a text value Changed content inside it.

If we wrote the following code using innerText:
document.querySelector("body").innerText = "<p>Changed content</p>";

<p>Changed content</p> would be displayed in the HTML page as a text node instead of Changed content as a text node inside an element node. The p tags won't be executed since they get converted to html entities. Therefore < gets converted to &lt;

The innerHTML property is much more useful as compared to innerHTML.

Adding content

Before beginning the discussion on this section it is good to make you get to introduced to some different types of adding. The factor differentiating between these types is just the place where content is added:

Taking the body element as a reference see the comments in the following code to get an idea of where content stands for what?

<!--Content before the BODY element-->
<body>
    <!--Content prepended to the BODY element-->
    <h1>A heading</h1>
    <p>A paragraph</p>
    <!--Content appended to the BODY element-->
</body>
<!--Content after the BODY element-->

So if we appended an empty p element to the body element, the code above would look like this:

<!--Content before the BODY element-->
<body>
    <!--Content prepended to the BODY element-->
    <h1>A heading</h1>
    <p>A paragraph</p>
    <p></p>
    <!--Content appended to the BODY element-->
</body>
<!--Content after the BODY element-->

And all other places work the same way! Now let's move on to see how to actually add content at the given places taking the body element as a reference.

innerHTML to the rescue!

The innerHTML property can also be used to add content to an HTML element. The trick is that we assign the HTML of a given element to its current value concatenated to some other to-be-added value. So if we want to append a p element to body we can simply do:

// for appending content
var ele = document.body;
ele.innerHTML = ele.innerHTML + "<p>An added paragraph</p>"; // Same as
// ele.innerHTML += "<p>An added paragraph</p>";

What happens here is that the innerHTML property of body gets assigned to its current innerHTML's value concatenated to the text we want to append.

In a slightly-similar way we can also prepend content:

// for prepending content
var ele = document.body;
ele.innerHTML = "<p>An added paragraph</p>" + ele.innerHTML;

Adding content before and after body using innerHTML is quite difficult and would sometimes even be impossible!

The appendChild() method

First let's talk about appending stuff. A highly useful way to append content to an HTML element is using the appendChild() method. This method takes as an argument a node and appends it to the selected DOM node. This means that you can't just pass it a string like <p>A paragraph</p> and get a p element appended - you have to pass a Node object.

But how to create nodes in JavaScript? Well its not a long thing to understand so let's deal with it first.

There are different ways to create different types of nodes. Whichever node you want to create just use its method. To create:

  1. Element nodes we have the document.createElement() method. It takes the name of the element to be created.
  2. Text nodes we have the document.createTextNode() method. It takes the value for the node.
  3. Comment nodes we have document.createComment() method. It also takes the value for the node.

With node creation covered we can now move on to see how to append some text to body:

var txt = document.body.createTextNode("Some text"); // a text node created with nodeValue - Some text
document.body.appendChild(txt); // a text node successfully appended to BODY

We first create a text node, give it a node-value and then append it to the body element. So simple!

Creating a comment node is exactly similar to creating a text node.

To create and append an element node isn't difficult either. For example to append a p element with some text, to body, we can simply do the following:

var ele = document.createElement("p"); // a p element node created
ele.innerHTML = "A paragraph"; // the element filled with some text
document.body.appendChild(ele); // Finally we append the complete p element to the BODY element

..or even the following:

var txt = document.body.createTextNode("A paragraph"); // a text node created with nodeValue - A paragraph
var ele = document.createElement("p"); // a p element node created
ele.appendChild(txt); // the text node appended to the p element
document.body.appendChild(ele); // Finally we append the complete p element with a text node to the BODY element

The insertBefore() method

Now let's talk of prepending content. To prepend content to an HTML element we can simply use the insertBefore() method. It takes as a reference another node before which to add the given node.

var ele = document.createElement("p"); // an element node created
ele.innerHTML = "A paragraph";

document.body.insertBefore(ele, document.body.childNodes[0]); // the second argument here is the node before which to add the first argument node
You can provide with any of the child nodes of the body element before which to add the desired paragraph. We used the childNodes property to select the first node of body and add content before it. Whichever node you choose just remember to use only a child of the the selected node.

append() and prepend()

A fairly new set of methods, append and prepend do the same work as appendChild() and insertBefore() respectively but with more ease and power (strings containing HTML tags can be appended directly). The functions are new and hence not compatible across all browsers so just consider this fact before using them in your programs. A much more compatible approach would be to use jQuery's content adding methods.

Replace content

Replacing content is another use of some of the methods of HTML DOM. To replace content in a web page you have two options: the innerHTML property using JavaScript regular expressions or the replaceChild() method. In this section we will only look at the latter, the former being complex and not even the solution sometimes.

The replaceChild() method takes a child node of the selected node and replaces it with the provided new node. Let's see an example:

var ele = document.body;

var prevNode = document.querySelector("h1"); // the node to replace

var newNode = document.createElement("h3"); // a new H3 element created
newNode.innerHTML = "A changed heading"; // some text given to the H3 element

ele.replaceChild(newNode, prevNode); // replace prevNode with newNode
One thing to remember is that the replaceChild() method only takes DIRECT CHILDREN of a selected node to be replaced. You can't replace the grand child of a given node using replaceChild() on it. The node on which performing this method must be the direct parent of the to-be-replaced node.

A trick to get over with this problem is to just refer to the parent of the to-be-replaced node using parentNode property like this:
var prevNode = document.querySelector("h1"); // the node to replace
var parent = prevNode.parentNode; // get to its direct parent
// instead of finding the parent ourself we just refer to it using this property

var newNode = document.createElement("h3"); // a new H3 element created
newNode.innerHTML = "A changed heading"; // some text given to the H3 element

parent.replaceChild(newNode, prevNode); // replace prevNode with newNode

Remove content

To remove content from a page, again you have, as a rather unusual option, the innerHTML property and as a better option the removeChild() method. The method just takes a node to be removed and, if found, removes it from the selected node. To remove the h1 element from the body element we can simply do:

var ele = document.body;
var trashNode = document.querySelector("h1"); // the node to remove
ele.removeChild(trashNode); // remove trashNode from BODY
..or even much better, using the parentNode property:
var trashNode = document.querySelector("h1"); // the node to remove
trashNode.parentNode.removeChild(trashNode); // remove trashNode from its parent

// Just for knowledge!
trashNode.parentNode; // returns null at this point since trashNode is no longer a part of the document and hence doesn't have a parent node currently.

In conclusion

With this we half complete our exploring journey on HTML elements, the half for their attributes. The things discussed in this chapter are highly common is many web pages and are necessary for any great developing! Make sure you make all the concepts in this whole chapter concrete as concrete!