DOM in JavaScript

JavaScript , Tue Jan 10 2023

    Intro to DOM

    DOM (Document Object Model) is a standard to access and share documents over internet.

    It represents how a particular document is structured. It helps programming languages like JavaScript and others to understand, modify the document.

    HTML, XML etc have different object models. we will focus on HTML DOM

    HTML DOM defines how an html page is structured, how it can be modified, properties and styles that can be added. various valid elements that can be used to structure a html page, version of the standard to be followed etc.

    HTML DOM is a tree of nested html elements that are defined while designing the html page. Certain rules must be followed as per the standard while defining the html page

    DOM is not a language but more of a standard to represent a document over the web. DOM is a set of nested tree where each node represents a particular html element.

    Core DOM is defines the basic things for all documents while specific DOMs like HTML DOM extends the core DOM to support HTML documents. Similarly XML and other documents.

    Accessing DOM

    DOM elements can be accessed and modified using the methods.

    A simple example is to get notified once DOM is available for use and we can proceed to manipulate it as and when needed

    <body onload="window.alert('document loaded')"></body>

    Another example is to add content to DOM dynamically once it is loaded. we will display todays date once the document is loaded

    <html>
        <head>
            <script>
                window.onload = function(){
                    const heading = document.createElement("h1");
                    const date = document.createTextNode(new Date().toString());
                    heading.appendChild(date);
                    document.body.appendChild(heading);
                }
            </script>
        </head>
    </html>

    In above examples we are using JavaScript language with used DOM methods like createElement or createTextNode or appendChild to modify the DOM.

    Also we are using DOM events like onload to do something when that event has fired. Although there are many events, the most commonly used are click, focus, blur

    Selecting Elements

    As we are aware one of the things we can do with JS is to modify or manipulate existing elements.

    Consider a simple scenario that we want to display the same thing below a input what user enters in it.

    We want to manipulate the element below the input somehow. The first step which we need to do is to identify or you can say select the element. we cannot modify something unless we now what to modify. We are here aware that we want to modify the element below an input. lets see how we can do the same in javascript.

    There are many ways to select an element.

    Finding HTML elements by id - The Easiest and the most efficient way to find an element id by id. We can assign some id to an element and can select that element as shown below.

    One thing that needs to be remembered is that all elements of a single web page should have unique ids.

    Consider that need for this as if there was same enrollment ids for multiple students in a college, then it would be difficult for college for further process like managing records for a particular student, his fees history, grade history etc.

    ...
        <div id="element-below-input"></div>
        ...
        <script>
            var element = document.getElementById("element-below-input");
        </script>

    Finding HTML elements by tag name - consider that for some reasons we want to manipulate all elements of a particular kind . Lets say we want to manipulate all images of our webpage which can be done as shown below.

    ...
        <img src="image1path" alt="image1" />
        <img src="image2path" alt="image2" />
        ...
        <script>
            var images = document.getElementsByTagName("img");
        </script>

    Finding HTML elements by class name - Class names are assigned to elements to style them uniquely. lets say to style all links in out website we had assigned some class say "our-link" to them and now we want to manipulate them.

    Finding HTML elements by CSS selectors - css selectors are that you can use any combination of class, id, tag name and many more to select a particular element.

    We will not go into detail as it itself can be an another topic. For example lets just say that we had given a same class "link" to all our links in web page as well as some span elemetns also to make them look like a link but now we just want to select all the span elements and not the links.

    ...
        <a class="link" href="link1">Link 1</a>
        <a class="link" href="link2">Link 2</a>
        <a class="link" href="link3">Link 3</a>
        <span class="link">Made to look like link</span>
        <span class="link">Also Made to look like link</span>
        ...
        <script>
        var dummylinks = document.querySelectorAll("span.link");
        </script>

    "span.link" - "span" is used to refer all span elements and ".link" is used to refer all elements with class "link". Combining both as above we are selecting all span elements with class "link"

    Element Properties and Methods

    Html elements can have different attributes assigned to them like id, class, type etc.

    There are standard attributes for different elements and when a browser identifies a standard attribute a corresponding DOM property is created and assigned to the element.

    These happens only for standard attributes only. Some attributes are applicable to all elements while some are applicable to particular ones only.

    For example id, class ... are applicable to all elements. While type is applicable to input element and button.

    if you assign type to a div and try to access it it is will be undefined.

    Attributes is what we assign in html. Properties is stored in DOM objects

    Some most used properties and methods are as below more can be found at

    Properties

    • classlist: a list of class assigned to an element - not a string its a array
    • id: string of the id assigned to an element
    • classname: string of classes assigned to an element - if there are more than one class separated by space
    • innerHtml: inner content of the element - if has nested elements then in string form
    • addEventListener: listen to a any type of event and call some function when that event has occurred. types can be click, mousedown, mouseup, focus, blur etc.
    • hasAttribute: method to check if an element has an attribute or not
    • removeAttribute: remove some attribute assigned to an element
    • getBoundingClientRect: returns the height, width, left and top values of an element related to the browser
    • removeEventListener: remove event listener from an element
    • scroll: scroll to an element position

    Usage of above properties is shown below

    ...
    <div id="div1" class="class1 class2"><span>hello</span></div>
    <input id="input" type="text">
    <button>button</button>
    ...
    <script>
    var element = document.getElementById("div1");
    console.log(element.classList); // ["div1", "div2", value: "div1 div2"]
    console.log(element.className); // "div1 div2"
    console.log(element.id); // "div1"
    console.log(element.innerHTML); // "<span>hello</span>"
    </script>

    Working with classes

    Mostly developers think classes are used mostly to style the elements.

    But it can also be used by javascript to do something to elements with a certain class.

    Any number of class names can be given to any of the HTML element, there isn't any restriction on that. However in case there are more than one class name being assigned to a HTML element, it must be separated by space" " between them. See below example for reference.

    <head>
        .menu-item {
            background-color: black;
            color: white;
        }
        .menu-item.active {
            background-color: white;
            color: black;
        }
    </head>
    <body>
        <ul>
            <li class="menu-item">Menu 1</li>
            <li class="menu-item active">Menu 2</li>
            <li class="menu-item">Menu 3</li>
        </ul>
    </body>

    That was an example of how class is used to style elements.

    Now lets see how to mix it up with javascript.

    First we need to select the elements with certain class and for that "getElementsByClassName()" method is used.

    We will add active class to the menu item when user clicks it and remove from the previous menu items if there any.

    Lets modify our above code to do that.

    <head>
            .menu-item {
                background-color: black;
                color: white;
            }
            .menu-item.active {
                background-color: white;
                color: black;
            }
    </head>
    <script>
        function memuClicked(currentElement){
            const menuItems = document.getElementsByClassName("menu-item");
            for (var i=0; i < menuItems.length; i++){
                menuItems[i].classList.remove('active');
            }
            console.log(currentElement);
            event.target.classList.add("active");
        }
    </script>
    <body>
        <ul>
            <li class="menu-item" onclick="memuClicked(this)">Menu 1</li>
            <li class="menu-item active" onclick="memuClicked(this)">Menu 2</li>
            <li class="menu-item" onclick="memuClicked(this)">Menu 3</li>
        </ul>
    </body>

    The above code works as we want but its not optimized. I will keep it upto you to figure what more can be done to make it better.

    Creating, Traversing and Removing Nodes

    Creating

    There are different ways to create html using javascript. The mostly used way is document.createElement method.

    Syntax

    document.createElement('tagname'); // tagname can be any valid html tag

    There can be some more options added to it but those are related to web components which we don't need to focus right now.

    But thats an interesting new thing if any one wants to peek into it.

    The created html element can be added attributes and content using the element properties and methods that we have already seen how to use them.

    The above method just creates the element but doesn't add it to the DOM. To add it to the DOM we will use appendChild method

    We can add it to any element or the main body also. We will get reference to the element to which we want to add new element using query selector

    Traversing Dom

    Sometimes we are not sure about the element to be manipulated directly but we are sure that we know something around it either its parent or children or something. There are some methods that can be used in such case

    <ul class="subjects">
            <li>Maths</li>
            <li class="fav-subject">Science</li>
            <li>English</li>
    </ul>
    <script>
            const subjects = document.querySelector("subjects");
            console.log(subjects.firstElementChild); // print first element of list
            console.log(subjects.lastElementChild); // print last element of list
            const favSub = document.querySelector("fav-subject");
            console.log(favSub.previousElementSibling); // prints element before favorite subject.
            console.log(favSub.nextElementSibling); // prints element after favorite subject.
            console.log(favSub.parentElement); // prints parent of favorite subject i.e entire list
    </script>

    We have similar methods to traverse with nodes

    • ele.childNodes
    • ele.firstChild
    • ele.lastChild
    • ele.previousSibling
    • ele.nextSibling
    • ele.parentNode

    Removing Nodes

    Another major thing that is needed while manipulating html is removing elements that are not needed after some action.

    Lets say there was one link for login and once user has logged its not needed anymore. so we need to remove that from DOM.

    const favSub = document.querySelector("fav-subject");
    favSub.remove(); // removes element from DOM

    remove method only removes element from DOM but it is still present in memory and can be added again as and when needed.