JavaScript DOM Manipulation
Have you ever tried to create a specific functionality when someone clicks on a button on your site? Or do you need some interactions when users interface with forms?
A HTML script is usually static with little functionality. HTML alone cannot maneuver elements to fit certain conditions or for interactivity. To have a web page that is interactive and dynamic, we need the DOM.
What is DOM
Document Object Model (DOM) is a programming interface for HTML and XML documents. JavaScript DOM is the API that JavaScript uses to communicate to static HTML elements, making them more functional.
The DOM is a tree-like representation of the contents of a webpage using nodes instead of elements. These nodes represent HTML elements, and they can be manipulated and re-rendered. With DOM, nodes act as objects, giving access to programming languages like JavaScript to modify, create, delete, remove, use, and transverse HTML elements.
DOM is a W3C (World Wide Web Consortium) standard. W3C specifications support it for HTML/CSS and ECMAScript for JavaScript. It runs on major browsers and supports cross-browser compatibility with some minor differences.
Accessing the DOM
The DOM is hierarchical, following a logical tree-like structure, where child nodes are contained in parent nodes. This arrangement is due to the HTML syntax structure where elements are embedded in each other, starting with the
All DOM actions start at the top of the document file. This is the first level of access. Then it works its way down to other node points, manipulating them according to instruction.
This HTML sample,
<DOCTYPE html>
<head>
<title>Html document</title>
<meta charset="utf-8">
</head>
<body>
<div>
<p>This is a paragraph</p>
<img src="img1.png" alt="img1">
<ul>
<li>List one</li>
<li>List two</li>
</ul>
</div>
</body>
</html>
Can be visualized like this in a DOM structure as follows,
DOM elements explained
These are HTML elements restructured as nodes. We can dissect each node object according to its position in the structure and its relationship with other nodes. Note that these positions and relationships change according to the HTML structure written by the developer.
- The Root Node: The root node is the <Doctype html> - typical for all html documents.
- The Parent Node: The Parent node is the node with a child or children. This node is a direct predecessor of any node. For example, the body is the parent node of div. Ul is the parent node of li.
- Child Node: The child nodes are nodes or elements that are housed within a parent node. For example, “<li>” is the child node of “<ul>”.
- Siblings Node: These are nodes on the same level. The two li are siblings. Meta and title are also siblings.
- Descendant Nodes: These are node objects inherited from a top level node. All nodes nested in a given node is a descendant of that node. P is a descendant of body. So is ul, img, li and div.
When working with DOM, certain actions are needed to target specific node objects. These actions are called Methods, and they have properties assigned to them. Asides from methods, JavaScript also has events attached to node objects. HTML DOM has lots of procedures that perform different operations on elements. Let's look at some DOM document methods.
QuerySelector()
The querySelector() method returns only the first child element that matches a specified CSS class, id, name, or tag.
<html>
<body>
<p>This is paragraph one</p>
<p>This is paragraph two</p>
<button onclick="func();">Click me</button>
<script>
function func(){
let n = document.querySelector("p").innerHTML = "This is query selector";
}
</script>
</body>
</html>
When you click the button, the first instance of <p>, which is "This is paragraph one," changes to "This is query selector."
QuerySelectorAll()
This changes all instances of the specified CSS selector.
<html>
<body>
<p class="para"> This is paragraph one </p>
<p class="para"> This is paragraph two </p>
<button onclick="func();">Click me</button>
<script>
function func(){
let n = document.querySelectorAll(".para").innerHTML = "This is a query selector";
}
</script>
</body>
</html>
Both paragraphs change to "This is query selector".
document.getElementByID
This method is a special one that targets the elements of specified IDs. You must define these IDs within the HTML. Unlike querySelectors() that can take the name, tag, ID, or class, document.getElementById is specific to IDs only, and it must carry the hashtag (#) sign.
<p>This is not a selected id</p>
<p id="new"> This is a selected id </p>
<button onclick="func();">Click me</button>
<script>
function func(){
let n = document.getElementById("#new");
n.style.color = "purple";
}
</script>
The text of the paragraph with id 'new' changes to purple.
document.getElementsByClassName
The elements are targeted with their class names. One than element can be targeted using class names.
<p class="new"> This is a selected id </p>
<script>
let n = document.getElementsByClassName("#new");
</script>
The same goes for getDocumentByTagName. This targets elements using their element name.
<p> This is a selected id </p>
<script>
let n = document.getElementByTagName(p);
</script>
innerHTML
The innerHTML modifies the content of an html element.
<p id="new"> This is a paragraph </p>
<script>
let a = document.getElementById("new").innerHTML = "This is now an innerHTML"
</script>
Methods for adding and removing elements
The appendChild(), insertBefore() and createElement() are separate methods but usually go together.
The createElement() creates a new element node that doesn't reflect on the DOM document. appendChild() or insertBefore() is used to add it to the document – this is why they usually work together. insertBefore adds a node as a child element, right before the specified element, while appendChild appends a node as the last child, after the specified element.
<p>Click the button to create a text in h1 <p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
var btn = document.createElement("h1");
document.body.appendChild(btn).innerHTML = "This!";
}
</script>
removeChild() and replaceChild()
The removeChild() removes a specific child node while the replaceChild() replaces the specified child node with another node. The removeChild is no longer supported on the DOM, although it still works on modern browsers. Nodes removed with node.removeChild() can be inserted into another document with the importNode() or adoptNode() methods. To use them in the same document, appendChild() or insertBefore() can be used.
Styling CSS Properties with .style Method
Besides HTML elements, Javascript DOM manipulations can be performed on CSS using the .style method. The syntax for this is quite simple. The variable name comes before the .style keyword followed by the .cssProperty. The .style method supports most CSS3 properties. CSS properties separated by a hyphen (-) like background-color and text-align are written in camelCase when using .style method. Background-color becomes backgroundColor.
You can use the .style method on advanced CSS3 properties like animation.
<div> Div</div>
<button onclick = "func();">click </button>
<script>
function func(){
let div = document.querySelector("div");
div.style.border = "5px solid yellow";
div.style.backgroundColor = "purple";
div.style.color = "white";
div.style.height = "200px";
div.style.width = "200px";
}
</script>
Manipulating image objects with DOM
Images can be created, styled, or altered with DOM using the DOM methods already discussed. You can set the image src, width, alt, and height and other properties using setAttribute() method.
<div class="container">
<button onclick="myFunction()">Try it</button>
<script>
function myFunction(){
const image = document.createElement("img");
image.setAttribute("src", "https://s23444.pcdn.co/wp-content/uploads/2020/01/Africa-general-pic.jpg.optimal.jpg");
image.setAttribute("height", "500")
document.querySelector(".container").appendChild(image)
}
</script>
Event Listeners
HTML DOM document allows a trigger on a page when a code is executed. This trigger is called an event. It is usually attached to a function, and executes when the function is called. This trigger could happen on button press, page load or while data input into web form fields.
Javascript DOM also allows different actions to be performed on HTML elements using the addeventlistener() function. Onclick, onmouseover, ondrag, onload, onchange, onmouseout, and onkeydown are some of the common events in Javascript. They are triggers that occur when an element is clicked, mouse hovered, dragged, on page load, element change, mouse moved away from it, or when a keyboard key is pressed respectively. There are many more Javascript DOM object events that could be attached to the addeventlistener() function. You can check them up here on W3Schools.
Using event listeners are highly encouraged when writing HTML DOM events. They are more readable, do not overwrite existing events and allow multiple events of the same type to be added to one element.
The following example is a simple way of using the addEventListener
<div id="new">This is an example of an an event listener</div>
<button id="clickhere">click</button>
<script>
button = document.getElementById("clickhere");
button.addEventListener("click", func);
function func(){
document.querySelector('div').style.color = "red";
}
</script>
The click in ("click", func) is the event to be handled by eventlistener. Mouseout, ondrag or any other event could be written in place of click; func() is the name of the function that is attached to the addEventListener() method.
To remove an event from an element, use the removeEventListener() method to exclude that event from the element.
Conclusion
Apart from the methods mentioned here, W3C specification supports over a hundred DOM styles, methods, events, documents, and event objects. It is interesting to note that although JavaScript DOM manipulation is quite popular amongst web developers, the DOM was designed in a way that other languages and libraries can implement it. JQuery, for example, is a popular library that is being used to execute methods.
Python and Java have official documentation and API parsers to transverse DOM nodes and create corresponding DOM objects.
In modern software engineering, programmers apply many of the JavaScript Frameworks to unify DOM use and standardize advanced functionalities.