JavaScript Modifying the document

The key to creating so-called “live” pages is DOM modification. In this chapter, we are going to show you how to create new elements on the fly, as well as modify the existing page content.

When writing apps or web pages, the first thing you will want to do is manipulating the document structure. Normally, it can be done by using the DOM.

Example: Show a Message

Let’s add a message on the page that looks better than alert. It will look like this:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
    <style>
      .alert {
        padding: 20px;
        font-size: 20px;
        border-radius: 5px;
        color: red;
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <div class="alert">
      Welcome to <strong>W3Docs</strong>.
    </div>
  </body>
</html>

And the same thing in javascript:

let div = document.createElement("div");
div.id = 'main';
div.style.padding = "20px";
div.style.fontSize = "20px";
div.style.background = "yellow";
div.style.color = "red";
div.innerHTML = "Welcome to";
document.body.appendChild(div);
let strong = document.createElement("strong");
strong.innerHTML = "W3Docs";
document.getElementById("main").appendChild(strong);

Above was demonstrated an HTML example. Now, let’s try creating the same div using JavaScript.

Creating an Element

There are two methods of creating DOM nodes. The first one is document.createElement(tag). It helps to create a new element node with the given tag, like here:

let input = document.createElement('input');

The second method is document.createTextNode(text), targeted at creating a new text node with the given text, like this:

let txtNode = document.createTextNode('Welcome to W3Docs');

Creating the Message

In the case below, it is a div with alert class and HTML inside:

let div = document.createElement('div');
div.className = "alert";
div.innerHTML = "Welcome to <strong>W3Docs</strong> ";
document.body.appendChild(div);

So, the element is created. Yet, it’s only in the variable. You can’t see it on the page, as it’s not a part of the document yet.

Methods of Insertion

For making the div show up, it is necessary to insert it into the document. For example, in the document.body.

A special method, such as document.body.append(div), can be used for it. The full code will look like this:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
    <style>
      #alert {
        padding: 20px;
        font-size: 20px;
        border-radius: 5px;
        color: red;
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <script>
      let div = document.createElement('div');
      div.id = "alert";
      div.innerHTML = "Welcome to <strong>W3Docs</strong> ";
      document.body.append(div);
    </script>
  </body>
</html>

And the same thing in javascript:

let div = document.createElement("div");
div.id = 'alert';
div.style.padding = "20px";
div.style.fontSize = "20px";
div.style.background = "yellow";
div.style.color = "red";
div.innerHTML = "Welcome to <strong>W3Docs</strong> "; 
document.body.appendChild(div);

Below is a set of methods, allowing to add items to a list and the text before/after it:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
  </head>
  <body>
    <ol id="ol">
      <li>One</li>
      <li>Two</li>
      <li>Three</li>
    </ol>
    <script>
      ol.before('before'); // insert string "before" before <ol>
      ol.after('after'); // insert string "after" after <ol>
      let li1 = document.createElement('li');
      li1.innerHTML = 'prepend';
      ol.prepend(li1); // insert li1 at the beginning of <ol>
      let liLast = document.createElement('li');
      liLast.innerHTML = 'append';
      ol.append(liLast); // insert liLast at the end of <ol>
    </script>
  </body>
</html>
before
1. prepend
2. One
3. Two
4. Three
5. append
after

And, the final list will look like this:

before
<ol id="ol">
  <li>prepend</li>
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
  <li>append</li>
</ol>
after

The mentioned methods are capable of inserting multiple lists of nodes and text pieces in one call.

In the following example, a string and an element are inserted:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
  </head>
  <body>
    <div id="div"></div>
    <script>
      div.before('<p>Welcome to W3Docs</p>', document.createElement('hr'));
    </script>
  </body>
</html>

The whole text is inserted as text. And, the final HTML will look as follows:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
  </head>
  <body>
    &lt;p&gt;Welcome to W3Docs&lt;/p&gt;
    <hr>
    <div id="div"></div>
  </body>
</html>

In brief, strings are inserted safely, like elem.textContent does it. So, such kinds of methods may be used to insert text pieces or nodes. And you may ask, what will happen if you insert HTML “as html”, including all tags and stuff working, like elem.innerHTML?

Let’s find it out.

insertAdjacentHTML/Text/Element

Another, more flexible method can be used for that is elem.insertAdjacentHTML(where, html). The initial parameter is a code word, indicating where to insert relative to elem. One of the following may be used:

  • "beforebegin" – inserting html at once before elem,
  • "afterbegin"– inserting html into elem, at the beginning,
  • "beforeend" – inserting html into elem, at the end,
  • "afterend" – inserting html at once after elem.

The second parameter will be an HTML string, inserted “as HTML”, like this:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
  </head>
  <body>
    <div id="div"></div>
    <script>
      div.insertAdjacentHTML('beforebegin', '<p>Welcome</p>');
      div.insertAdjacentHTML('afterend', '<p>Bye</p>');
    </script>
  </body>
</html>

The result will be the following:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
  </head>
  <body>
    <p>Welcome</p>
    <div id="div"></div>
    <p>W3Docs</p>
  </body>
</html>

Let’s check out the picture of insertion variants, in which you can notice similarities between it and the previous picture. The insertion points are similar, yet this method inserts HTML.

Node Removal

The method of node.remove() is used for removing a node. In the case below, you can see how to make your message disappear after a second:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
    <style>
      #alert {
        padding: 20px;
        font-size: 20px;
        border-radius: 5px;
        color: red;
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <script>
      let div = document.createElement('div');
      div.id = "alert";
      div.innerHTML = "Welcome to <strong>W3Docs</strong>";
      document.body.append(div);
      setTimeout(() => div.remove(), 1000);
    </script>
  </body>
</html>

And the same thing in javascript:

let div = document.createElement('div');
div.id = "alert";
div.style.padding = "20px";
div.style.fontSize = "20px";
div.style.background = "yellow";
div.style.color = "red";
div.innerHTML = "Welcome to <strong>W3Docs</strong> ";
document.body.append(div);
setTimeout(() => div.remove(), 1000);

Please, take into account that for moving an element to another place, you don’t have to remove it from the old one. All the insertion methods can automatically remove the node from the old place.

In the example below, the swapping of elements is demonstrated:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
  </head>
  <body>
    <div id="first">First</div>
    <div id="second">Second</div>
    <script>
      // no need to call remove
      second.after(first); // take #second and after it insert #first
    </script>
  </body>
</html>

Cloning nodes: cloneNode

Now, let’s see how to insert another similar message.

For that, you can make a function and put the code there. There is also an alternative way: cloning the existing div and modifying the text inside it. Sometimes, having a big element can make it faster and simpler.

  • The elem.cloneNode(true) call will create a deep clone of the element along with all subelements and attributes. In the case of calling elem.cloneNode(false), the clone will be made without any child elements.

Here is an example of copying the message:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
    <style>
      #div {
        padding: 20px;
        font-size: 20px;
        border-radius: 5px;
        color: red;
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <div class="alert" id="div">
      Welcome to <strong>W3Docs.</strong>
    </div>
    <script>
      let div2 = div.cloneNode(true); // clone the message
      div2.querySelector('strong').innerHTML = 'Javascript book.'; // change the clone
      div.after(div2); // show the clone after the existing div
    </script>
  </body>
</html>

DocumentFragment

DocumentFragment is a special DOM node, which serves as a wrapper for passing around lists of nodes. You can also append other nodes to it. But when you insert it somewhere, its content will be inserted instead. For instance, getListContent creates a fragment with <li> items that are later inserted into <ul>, like in the example below:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
  </head>
  <body>
    <ul id="ul"></ul>
    <script>
      function getListContent() {
        let fragment = new DocumentFragment();
        for(let i = 1; i <= 5; i++) {
          let li = document.createElement('li');
          li.append(i);
          fragment.append(li);
        }
        return fragment;
      }
      ul.append(getListContent()); // (*)
    </script>
  </body>
</html>

At the last line (*), DocumentFragment is inserted, and its resulting structure will look like this:

<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>

As a rule, DocumentFragment is rarely used in an explicit way. So, you can return an array of nodes instead, like this:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
  </head>
  <body>
    <ul id="ul"></ul>
    <script>
      function getListContent() {
        let result = [];
        for(let i = 1; i <= 5; i++) {
          let li = document.createElement('li');
          li.append(i);
          result.push(li);
        }
        return result;
      }
      ul.append(...getListContent()); // append + "..." operator = friends!
    </script>
  </body>
</html>

About “Document.write”

The document.write is an ancient method of adding something to a web page.

The syntax of document.write is the following:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the Document</title>
  </head>
  <body>
    <p>Hello</p>
    <script>
      document.write('<b>Welcome to JS book</b>');
    </script>
    <p>The end</p>
  </body>
</html>

By calling document.write(html), you can write the html into the page “right here and now”. The string of html is flexible; it can be dynamically generated. So, you can use JavaScript for creating a full fledged webpage.

This method was created in ancient times but is still alive, as there are scripts that use it. But, document.write works only when the page is loading.




Do you find this helpful?

Related articles