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>
<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:
var 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);
var strong = document.createElement("strong");
strong.innerHTML = "Web";
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 for 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 Web');
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>Web</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>
<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>Web</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>Web</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>
</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>
<body>
<div id="div"></div>
<script>
div.before('<p>Welcome to Web</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>
<body>
<p>Welcome to W3Docs</p>
<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>
<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>
<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>
<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>Web</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>Web</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>
<style>
</style>
</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>
<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>Web.</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>
<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>
<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>
<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.
0 Comments
CAN FEEDBACK
Emoji