DOM in Depth

DOM in Depth

The Document Object Model, or DOM for short, is a powerful tool that allows web developers to dynamically add, remove, and modify elements on a web page.

It's like having a magic wand to change a website's appearance and functionality with just a few lines of code. This article will explore using the DOM to add and remove elements, modify existing elements, and attach event listeners.

In the last module on DOM, we learned how to access the DOM elements. So, in this module, with the help of knowledge from the last class, we will learn how to add or remove elements from DOM.

Adding and Removing elements from DOM:

Adding an element:

To add an element to the Document Object Model (DOM), we must first create the element.

We can create a new HTML element using the JavaScript method document.createElement().

This method takes the name of an HTML tag as an argument and returns a new Node object of the Element type.

let element = document.createElement(htmlTag);

The above code will create an HTML element of the specified parameters.

Consider the HTML document without any div element. We can create a new div element using the **document.createElement()**method and then use the appendChild() method to add the created div element to the DOM tree.

This can be demonstrated with the help of the following example.

<!DOCTYPE html>
<html>
<head>
    <title>JS CreateElement Demo</title>
</head>
<body>

</body>
</html>

Now, we will use the document.createElement() to create a new <div> element as shown below:

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

After creating the div element, we can add HTML content to it using the innerHTML property. Let's modify our previous example accordingly:

div.innerHTML = '<p>CreateElement example</p>';

Next, we can attach the newly created div element to the document using the appendChild() method.

document.body.appendChild(div);

In the code snippet above, the appendChild() method has been applied to the body element because the intention is to add the newly created div element to the body of the document.

joining all the above code, the combined HTML code becomes:

<!DOCTYPE html>
<html>
<head>
    <title>JS CreateElement Demo</title>
</head>
<body>
    <script>
        let div = document.createElement('div');
        div.innerHTML = '<p>CreateElement example</p>';
        document.body.appendChild(div);
    </script>
</body>
</html

Let’s discuss in detail about appendChild() method:

The appendChild() method is a part of the Node interface in JavaScript, which enables you to add a new node to the end of the child nodes list of a specific parent node.

The syntax of the appendChild() method is as follows:

parentNode.appendChild(childNode);

The appendChild() method is used to add a child node to a parent node. The new child node is specified as the childNode parameter in the method. The appendChild() method returns the appended child.

If the childNode parameter references an existing node in the document, the appendChild() method will move the childNode from its current position to the new position specified in the method.

Consider the example shown below:

Suppose you have given the following HTML document:

<ul id="menu">
</ul>

Now, we want to add the list items i.e., <li> elements to this list , now see the code below:

function createMenuItem(name) {
    let li = document.createElement('li');
    li.textContent = name;
    return li;
}
// get the ul#menu
const menu = document.querySelector('#menu');
// add menu item
menu.appendChild(createMenuItem('Home'));
menu.appendChild(createMenuItem('Services'));
menu.appendChild(createMenuItem('About Us'));

How the code works:

  1. The createMenuItem() function creates a new list item element with a specified name using the createElement() method.

  2. The querySelector() method is used to select the <ul> element with the id menu.

  3. The createMenuItem() function is called to create a new menu item and the appendChild() method is used to append the menu item to the <ul> element.

Output:

<ul id="menu">
    <li>Home</li>
    <li>Services</li>
    <li>About Us</li>
</ul>

Removing an element:

The removeChild() method can be used to remove a child element from a node. The syntax for the removeChild() method is as follows:

let childNode = parentNode.removeChild(childNode);

The removeChild() method removes the specified child node from its parent node in the DOM tree. The childNode parameter specifies the child node that you want to remove from the parentNode. If the childNode is not a child of the parentNode, the method throws an exception.

The removeChild() method returns the removed child node from the DOM tree but still keeps it in the memory for future use.

If you don't need to keep the removed child node in the memory, you can use the following syntax instead:

parentNode.removeChild(childNode);

The child node will be present in the memory until it is deleted by the JavaScript garbage collector.

Consider the following example, which demonstrates how to remove a child element from a node using the removeChild() method:

Suppose we have an HTML markup with a list element as shown below:

<ul id="menu">
    <li>Home</li>
    <li>Products</li>
    <li>About Us</li>
</ul>

Now, consider that you want to remove the last child element:

let menu = document.getElementById('menu');
menu.removeChild(menu.lastElementChild);

The code removes the last element of an unordered list using the removeChild() method. Here is how it works:

  • First, the ul element with the id menu is obtained using the getElementById() method.

  • Then, the removeChild() method is used to remove the last element of the ul element. The menu.lastElementChild property returns the last child element of the menu, which is then passed as an argument to the removeChild() method. This removes the last child element from the menu element.

If you want to remove all child elements of an element, you can follow the steps given below:

  • First, get the first node of the element using the firstChild property.

  • Then, use a loop to repeatedly remove the child node until there are no child nodes left.

The following code shows how to remove all list items of the menu element:

let menu = document.getElementById('menu');
while (menu.firstChild) {
    menu.removeChild(menu.firstChild);
}

Now let's explore how we can modify an element's attributes in our HTML document.

Modifying element’s attributes:

Let’s first discuss the connection between HTML attributes and DOM properties:

When a web browser loads an HTML page, it creates corresponding DOM objects based on the DOM nodes of the document.

For instance, if the page includes the following input element:

<input type="text" id="username">

When a web browser loads an HTML page, it generates corresponding DOM objects based on the DOM nodes of the document.

For example, an input element on a page will generate an HTMLInputElement object. The input element has two attributes: type with the value text, and id with the value username.

After the web browser loads an HTML page, it creates the corresponding DOM objects based on the DOM nodes present in the document.

  • The input.type with the value text.

  • The input.id with the value username.

To access both standard and non-standard attributes, you can use the following methods:

  • element.getAttribute(name) to get the value of the attribute.

  • element.setAttribute(name, value) to set the value of the attribute.

  • element.hasAttribute(name) to check for the existence of the attribute.

  • element.removeAttribute(name) to remove the attribute.

getAttribute()

To obtain the value of a particular attribute of an element, you can use the getAttribute() method of the element.

This method needs to be called on the element, and the name of the attribute whose value is to be retrieved should be passed as an argument to the method.

let value = element.getAttribute(name);

Parameters

The getAttribute() accepts an argument which is the name of the attribute from which you want to return the value.

Return value

When the specified attribute exists on the element, the getAttribute() method returns a string representing the value of the attribute. However, if the attribute does not exist on the element, the method returns null.

Consider the example below:

<!DOCTYPE html>
<html>
<body>

    <a href="<https://www.javascripttutorial.net>" 
        target="_blank" 
        id="js">JavaScript Tutorial
    </a>

    <script>
        let link = document.querySelector('#js');
        if (link) {
            let target = link.getAttribute('target');
            console.log(target);
        }
    </script>
</body>
</html>

Output:

_blank

To retrieve the target attribute of the link element with the id "js", follow these two steps:

  1. Use the querySelector() method to select the link element.

  2. Call the getAttribute() method to obtain the target attribute of the selected link element.

setAttribute() method:

To set a value of an attribute on a specified element, you use the setAttribute() method:

element.setAttribute(name, value);

Parameters

When using the setAttribute() method on an HTML element, the name parameter specifies the name of the attribute whose value is being set. If the attribute name is in uppercase, it will be automatically converted to lowercase. The value parameter specifies the value to be assigned to the attribute. If a non-string value is passed to the method, it will be automatically converted to a string.

Return value

After setting an attribute on an element using the setAttribute() method, it doesn't return any value, and its return value is undefined. If the attribute is already present on the element, the setAttribute() method updates the value of the attribute; otherwise, it creates a new attribute with the given name and value.

It's common practice to use querySelector() or getElementById() to select an element before calling the setAttribute() method on it.

Consider the example shown below:

<!DOCTYPE html>
<html>
<body>
    <button id="btnSend">Send</button>

    <script>
        let btnSend = document.querySelector('#btnSend');
        if (btnSend) {
            btnSend.setAttribute('name', 'send');
        }
    </script>
</body>
</html>

Output:

<button id="btnSend" name="send">Send</button>

To set the value of the name attribute to send on the button element with the id btnSend, follow these two steps:

  1. Use the querySelector() method to select the button element with the id btnSend.

  2. Call the setAttribute() method on the selected button element, and set the name attribute to send.

hasAttribute() method:

To determine whether an element has a particular attribute, you can use the hasAttribute() method.

let result = element.hasAttribute(name);

Parameters

The hasAttribute() method accepts an argument that specifies the name of the attribute that you want to check.

Return value

The hasAttribute() method returns a Boolean value that indicates whether an element has the specified attribute or not. If the element contains the attribute, the hasAttribute() method returns true; otherwise, it returns false.

removeAttribute() method:

You can use the removeAttribute() method to delete an attribute with a specific name from an element.

element.removeAttribute(name);

Parameters

To remove an attribute from an element, you can use the removeAttribute() method and pass the name of the attribute as an argument. If the attribute doesn't exist, the removeAttribute() method won't throw an error.

Return value

After removing an attribute from an element using the removeAttribute() method, it doesn't return any value, and its return value is undefined.

These are the various ways to modify the attributes of an element. Now, let's move on to learning about EventListeners.

Event Listeners:

An event is an action that takes place in a web browser and triggers a response that you can react to.

For instance, when users click a button on a web page, you may want to respond to this click event by showing a dialog box.

Each event can have an associated event handler, which is a code block that executes when the event occurs.

An event handler is also referred to as an event listener since it listens for the event and performs a task when the event occurs.

Event Flow:

For understanding Event flow consider the HTML document given below:

<!DOCTYPE html>
<html>
<body>
    <div id="container">
        <button id='btn'>Click Me!</button>
    </div>
</body>

Clicking a button triggers not only the button but also its container, the div , and the entire webpage.

Event flow describes the sequence in which events are received on the page, starting from the element where the event occurs and then propagated through the DOM tree.

There are two primary event models: event bubbling and event capturing.

Event Bubbling:

Under the event bubbling model, an event begins at the most specific element and moves upward towards the least specific element (such as the document or window). When you click a button, the click event takes place in the following order:

  1. The button

  2. The div with the id container

  3. The body element

  4. The html element

  5. The document object

The click event initially occurs on the button that was clicked, then propagates up the DOM tree, triggering on each node along the way until it reaches the document object.

Consider the following picture shown below:

Event Capturing:

The event-capturing model is characterized by the event starting at the least specific element and then flowing down toward the most specific element.

For instance, when you click on a button, the click event will occur in the following order:

  1. document

  2. html

  3. body

  4. div with the id container

  5. button.

Consider the following picture below:

As we learned previously, an event executes a block of code known as an event handler or event listener.

An event can have one or multiple event handlers, and all of them will be executed when the event is triggered.

There are several ways to handle events, including:

HTML Event Handler Attributes:

Usually, event handlers are named with an "on" prefix, such as "onclick" for the click event.

To link an event handler with an HTML element, you can use an HTML attribute with the event handler's name.

Here's an example:

<input type="button" value="Save" onclick="alert('Clicked!')">

In the previous example, the onclick attribute is set to call the showAlert() function defined in the JavaScript code.

Using this method, you can keep the HTML code clean and put all the event handling code in the JavaScript code.

It's a best practice to separate the behavior from the content by keeping the event handling code separate from the HTML code.

<script>function showAlert() {
        alert('Clicked!');
    }
</script><input type="button" value="Save" onclick="showAlert()">

When the button is clicked in the above example, it triggers the execution of the showAlert() function.

Disadvantages of using HTML event handler attributes:

Using HTML event handler attributes to assign event handlers is generally considered a bad practice and should be avoided due to the following reasons:

Firstly, it can make the code more difficult to maintain and extend since the event handler code is mixed with the HTML code.

Secondly, it can cause timing issues. If the element is fully loaded before the JavaScript code, users can start interacting with the element on the webpage, which can result in errors.

Therefore, there are alternative methods for assigning event handlers that should be used instead.

addEventListener() method:

addEventListener() - registers an event handler

syntax:

element.addEventListener(event, function, useCapture)

The addEventListener() method requires three arguments:

  • an event, a function, and an optional boolean value for useCapture.

  • The event argument is a string that specifies the name of the event. The function argument is a required parameter and defines the JavaScript code that responds to the event.

  • The useCapture parameter is optional, and its default value is false. It determines whether the event is executed in the capturing or bubbling phase. When set to true, the handler executes in the capturing phase, and when set to false, the handler executes in the bubbling phase.

To add an event listener to the button element with the ID property "btn" and execute a function on click, we can use the addEventListener() method.

Here's an example code snippet:

let btn = document.querySelector('#btn');
btn.addEventListener('click',function(event) {
    alert(event.type); // click
});

The code example above shows how to add multiple event handlers to a single event. In this example, there is a button with an ID of myButton. Three event handlers are added to handle the click event of this button. Each event handler is defined as a separate function.

First, the handleFirstClick function is added to the button as an event listener. Then, the handleSecondClick function is added using the addEventListener method with the third argument as true, which means the event handler executes in the capturing phase.

Finally, the handleThirdClick function is added using the addEventListener method with the third argument as false, which means the event handler executes in the bubbling phase.

When the button is clicked, all three event handlers will be executed in the order of capturing phase, a target phase, and a bubbling phase.

let btn = document.querySelector('#btn');
btn.addEventListener('click',function(event) {
    alert(event.type); // click
});

btn.addEventListener('click',function(event) {
    alert('Clicked!');
});

Activity 2

State True or False:

  • addEventListener() method has four arguments i.e. event, callback, value, useCapture.

  • An event refers to a particular action that occurs within a web browser and leads to a response that can be responded to.

  • In the event-capturing model, events typically begin from the most specific element and then propagate downwards towards the least specific element.

removeEventListener() method:

The removeEventListener() method is used to remove an event listener that was previously added using the addEventListener() method.

The arguments passed to removeEventListener() must match the arguments that were passed to addEventListener().

Consider the following example:

let btn = document.querySelector('#btn');

// add the event listener
let showAlert = function() {
    alert('Clicked!');
};
btn.addEventListener('click', showAlert);

// remove the event listener
btn.removeEventListener('click', showAlert);

The code above demonstrates the use of the removeEventListener() method to remove an event handler previously added using the addEventListener() method. It is important to note that the same arguments must be passed to removeEventListener() as were passed to addEventListener(). Additionally, anonymous functions cannot be used as arguments in removeEventListener().

There are various different events to which user can listen and add handlers:

Event PerformedEvent HandlerDescription
clickonclickAn event occurs when the user clicks on an element with a mouse.
mouseoveronmouseoverAn event occurs when the cursor of the mouse comes over an element.
mouseoutonmouseoutAn event occurs when the cursor of the mouse leaves an element.
mousedownonmousedownAn event occurs when the user presses the mouse button over an element.
mouseuponmouseupAn event occurs when the user releases the mouse button over an element.
mousemoveonmousemoveAn event occurs when the mouse moves over an element.
Keydown & Keyuponkeydown & onkeyupAn event occurs when the user presses and releases a key.
focusonfocusAn event occurs when the user focuses on an element.
submitonsubmitAn event occurs when the user submits a form.
bluronblurAn event occurs when the focus is away from a form element.
changeonchangeAn event occurs when the user modifies or changes the value of a form element.
loadonloadAn event occurs when the browser finishes loading the page.
unloadonunloadAn event occurs when the visitor leaves the current webpage and the browser unloads it.
resizeonresizeAn event occurs when the visitor resizes the window of the browser.

onclick, onmouseover, onfocus, onkeydown:

<html>
<head> Javascript Events </head>
<body>

//onclick
<form>
<input type="button" onclick="clickevent()" value="Who's this?"/>
</form>

//mouseover
<p onmouseover="mouseoverevent()"> Keep cursor over me</p>

//focus
<h2> Enter something here</h2>
<input type="text" id="input1" onfocus="focusevent()"/>

//keydown
<h2> Enter something here</h2>
<input type="text" id="input1" onkeydown="keydownevent()"/>

<script>

    //onclick
    function clickevent()
    {
        document.write("This is JavaTpoint");
    }

    //mouseover
    function mouseoverevent()  
  {  
        alert("This is JavaTpoint");  
  }

    //focus
    function focusevent()
    {
        document.getElementById("input1").style.background=" aqua";
    }

    //keydown
    function keydownevent()
    {
        document.getElementById("input1");
        alert("Pressed a key");
    }

</script>
</body>
</html>

Now that we have learned about events and their handling, let's move on to modifying CSS.

We can start by learning how to set inline styles.

Setting Inline Styles:

The style property of an element is used to set its inline style.

element.style

The style property retrieves a read-only CSSStyleDeclaration object that contains a collection of CSS properties. To set a CSS property, such as color, for an element and make it appear red, you can use the following code:

element.style.color = 'red';

In case the CSS property contains hyphens (-) like -webkit-text-stroke, you can access it using the array-like notation ([]):

element.style.['-webkit-text-stock'] = 'unset';

You can completely override the existing inline style by setting the cssText property of the style object. Here's an example:

element.style.cssText = 'color:red;background-color:yellow';

Or the setAttribute() method can be used:

element.setAttribute('style','color:red;background-color:yellow');

After setting the inline style of an element, you can modify one or more CSS properties:

element.style.color = 'blue';

If you don't want to replace all the existing CSS properties with a new one, you can append the new CSS property to the cssText property using string concatenation. Here's an example:

element.style.cssText += 'color:red;background-color:yellow';

Here, the operator "+=" is used to concatenate the new style string with the existing one.

Manipulating CSS Classes:

The className property is used to retrieve the CSS classes of an element and returns them as a string separated by spaces.

element.className

Consider an unordered list (ul) element as follows:

<ul id="menu" class="vertical main"><li>Homepage</li><li>Services</li><li>About</li><li>Contact</li></ul>

The below code demonstrates how to get the classes of the **ul** element on the Console window:

let menu = document.querySelector('#menu');
console.log(menu.className);

Output:

vertical main

The following code can be used to assign a class to an element:

element.className += newClassName;

The += operator adds the newClassName to the existing class list of the element.

The classList property of an element is read-only and it returns a collection of CSS classes that can be modified to add, remove, or toggle classes of the element.

const classes = element.classList;

The classList property of an element returns a read-only DOMTokenList object that represents the classes in the element's class attribute.

Despite being read-only, you can still modify the classes using various methods. Let's look at some examples to understand these methods.

Consider the following HTML snippet as an example:

<div id="content" class="main red">JavaScript classList</div>

To get the classes of an element, we can use the classList property of the element as follows:

let div = document.querySelector('#content');
for (let cssClass of div.classList) {
    console.log(cssClass);
}

Output:

main
red

How it works:

  • In the code above, we first select the div element with the content id using the querySelector() method.

  • We then iterate over the elements of its classList and display the classes in the Console window.

Adding one or more classes to the class list of an element:

To include one or more CSS classes in the class list of an element, you can use the add() method of the classList.

For instance, the code below adds the info class to the class list of the div element with the id content:

let div = document.querySelector('#content');
div.classList.add('info');

You can use the add() method of the classList property to add one or more CSS classes to an element.

let div = document.querySelector('#content');
div.classList.add('info','visible','block');

Removing element’s classes:

You can remove a CSS class from the class list of an element by using the remove() method, which is a part of classList.

let div = document.querySelector('#content');
div.classList.remove('visible');

Similar to the add() method, you can remove multiple classes at once using the remove() method.

let div = document.querySelector('#content');
div.classList.remove('block','red');

Did you find this article valuable?

Support Arul Johnson by becoming a sponsor. Any amount is appreciated!