The power of JavaScript is its use in dynamically displaying and manipulating elements on a webpage written in HTML. We know that an HTML page consists of elements such as <head><body> <h1> tags or text fields and buttons. The DOM or Document Object Model represents the structure of these elements as a "tree" data structure after your web browser reads a page. The DOM Application Programming Interface (API) contains methods that provide JavaScript access to these elements. Start by reading this article to learn about the document structure of the DOM and how to find, create and change elements.
Say we want to write a script that replaces all images (<img>
tags) in the document with the text held in their alt
attributes, which specifies an alternative textual
representation of the image.
This involves not only removing the images but adding a new text node to replace them. Text nodes are created with the
document.
method.
<p>The <img src="img/cat.png" alt="Cat"> in the <img src="img/hat.png" alt="Hat">.</p> <p><button onclick="replaceImages()">Replace</button></p> <script> function replaceImages() { let images = document.body.getElementsByTagName("img"); for (let i = images.length - 1; i >= 0; i--) { let image = images[i]; if (image.alt) { let text = document.createTextNode(image.alt); image.parentNode.replaceChild(text, image); } } } </script>
Given a string, createTextNode
gives us a text node that we can insert into the document to make it show up on the screen.
The loop that goes over the images starts at the end of the list. This is necessary because the node list returned by a method like
getElementsByTagName
(or a property like childNodes
) is live. That is, it is updated as the document changes. If we started from the front, removing the first image would cause the list
to lose its first element so that the second time the loop repeats, where i
is 1, it would stop because the length of the collection is now also 1.
If you want a solid collection of nodes, as opposed to a live one, you can convert the collection to a real array
by calling Array.from
.
let arrayish = {0: "one", 1: "two", length: 2}; let array = Array.from(arrayish); console.log(array.map(s => s.toUpperCase())); // → ["ONE", "TWO"]
To create element nodes, you can use the document.
method. This method takes a tag name and returns a new empty node of the given type.
The following example defines a utility elt
, which creates an element node and treats the rest
of its arguments as children to that node. This function is then used to add an attribution to a quote.
<blockquote id="quote"> No book can ever be finished. While working on it we learn just enough to find it immature the moment we turn away from it. </blockquote> <script> function elt(type, ...children) { let node = document.createElement(type); for (let child of children) { if (typeof child != "string") node.appendChild(child); else node.appendChild(document.createTextNode(child)); } return node; } document.getElementById("quote").appendChild( elt("footer", "—", elt("strong", "Karl Popper"), ", preface to the second edition of ", elt("em", "The Open Society and Its Enemies"), ", 1950")); </script>