Goodbye jQuery...

As the web standards becoming more mature each day, my prediction is that the need for third-party JavaScript library such as jQuery will slowly decline. jQuery is indeed still one of the best client-side JavaScript library in my opinion and even I still use it on some of my projects, but as the web application becoming more complex, programmers will starting to look at browser's native solution which will (maybe) offers better performance than the third-party library. In this post i will show you some of the browser's native API for replacing jQuery's DOM selector method, the obvious "$" or "jQuery" function. Under the hood, jQuery is actually using Sizzle library for its DOM selector, which i believe (even though I haven't dig inside the source code) Sizzle also using some of the browser's native API.

DOM selector with document.querySelector(selectors)

As the name already suggests, this method under the Document object fetch the first element within the document that matches the specified selector, or group of selectors. If no matches are found, null is returned. One important thing that we need to know here is that, using this method will return "null" value when no matches were found. For those who familiar with jQuery need to pay attention as the jQuery selector always returns empty Array when no matches were found. Below I show you some example.

<!doctype html>
<html><head><title>Query Selector in JavaScript</title><meta charset="UTF-8"></head>
<body>
<div>This is the first DIV</div>
<div>This is the second DIV</div>
<div>This is the third DIV</div>
<div>This is the fourth DIV</div>
<div>This is the fifth DIV</div>
<script>
    // get the first DIV
    let firstDiv = document.querySelector('div');
    console.log('This is ', firstDiv);

    // get the second DIV
    let secondDiv = document.querySelector('div:nth-of-type(2)');
    console.log('This is the ', secondDiv);
    // change the text color to blue
    secondDiv.style.color = 'blue';

    // get the third DIV
    let thirdDiv = document.querySelector('div:nth-of-type(3)');
    console.log('This is the ', thirdDiv);
    // change the text format to bold
    thirdDiv.style.fontWeight = 'bold';

    // check if element exists
    let sixthDiv = document.querySelector('div:nth-of-type(6)');
    if (sixthDiv == null) {
        // add the sixth div if it is not exists yet
        let newDiv = document.createElement("div")
        newDiv.innerText = 'This is the sixth DIV';
        document.body.append(newDiv);
    }   
</script>
</body>
</html>

Tree traversal

querySelector method accepts all type of CSS selector and can be used to do DOM element tree traversal. In fact I already showed one of it the first example using nth-of-type(n) modifier. You can of course use parent children relationship selector also in this case.

<!doctype html>
<html><head><title>Query Selector in JavaScript</title><meta charset="UTF-8"></head>
<body>
<div id="parent">
  <div class="child">
    <div class="grandchild">
      <div class="great_grandchild"></div>
    </div>
  </div>
  <div class="child">
    <div class="grandchild"></div>
  </div>
</div>
<script>
    /* TREE TRAVERSAL */
    // get the first direct child under parent
    let firstChild = document.querySelector('#parent > .child');
    console.log('This is the ', firstChild); 
    
    // get the great grandchild under parent
    let greatGrandChild = document.querySelector('#parent .great_grandchild');
    console.log('This is the ', greatGrandChild);

    // alternative syntax to get the great grandchild
    greatGrandChild = firstChild.querySelector('.great_grandchild');
    console.log('This is the ', greatGrandChild);

    // add new first child under parent
    let newFirstChild = document.createElement("div");
    newFirstChild.innerText = 'The real 1st child';
    document.querySelector('#parent').prepend(newFirstChild);

    // get the parent of great grandchild
    let parentOfGrandChild = greatGrandChild.parentNode;
    console.log(parentOfGrandChild);
</script>
</body>
</html>

Multiple DOM element matches and manipulation with querySelectorAll

The querySelectorAll method behaves almost similar with the querySelector, except that it returns not only single match but an array in form of NodeList object instead. You can use this if you want to manipulate more than one element that match with your specified selector. Just remember to add :scope pseudo class at the very first of selector string to make sure the browser only get the child element under the specified element.

<!doctype html>
<html><head><title>Query Selector in JavaScript</title><meta charset="UTF-8"></head>
<body>
<ul id="bio">
    <li class="name">The first one</li>
    <li class="location">Tsukuba, Japan</li>

    <li class="name">The second one</li>
    <li class="location">Tokyo, Japan</li>

    <li class="name">The third one</li>
    <li class="location">Jakarta, Indonesia</li>

    <li class="name">The fourth one</li>
    <li class="location">Seoul, South Korea</li>

    <li class="name">The fifth one</li>
    <li class="location">Wuhan, China</li>
</ul>
<script>
    /* querySelectorAll */
    // get all names
    let names = document.querySelectorAll(':scope #bio .name');
    console.log('Number of names ', names.length);
    console.log('The elements are ', names);

    // get all locations
    let locations = document.querySelectorAll(':scope #bio .location');
    console.log('The elements are ', locations);

    // make all location texts italic
    locations.forEach(e => e.style.fontStyle = 'italic');

    // prepend "name" text inside name element
    names.forEach(e => e.prepend('Name: '));

    // add empty list element with bottom border after location
    // as a data separator
    locations.forEach(function(e){
        let borderedList = document.createElement('li');
        borderedList.style.borderBottom = '1px solid #999';
        e.after(borderedList);
    }); 
</script>
</body>
</html>

Pretty neat huh? :D

Sibling manipulation with previousElementSibling and nextElementSibling

It is very often we want to manipulate DOM elements which are positioned on the same level as current selected element, or the siblings of current element. In this case we can use the previousElementSibling and nextElementSibling property.

<!doctype html>
<html><head><title>Query Selector in JavaScript</title><meta charset="UTF-8"></head>
<body>
<div id="friends">
    <div class="friend">Harada</div>
    <div class="friend">Sasaki</div>
    <div class="friend">Iqbal</div>
    <div class="friend">Michael</div>
    <div class="friend">Megumi</div>
</div>
<script>
    /* SIBLINGS */
    // get iqbal
    let iqbal = document.querySelector('#friends .friend:nth-of-type(3)');
    console.log(iqbal);

    // who is our friend before iqbal
    let beforeIqbal = iqbal.previousElementSibling;
    // change the color to orange
    beforeIqbal.style.color = 'orange';

    // who is our friend after iqbal
    let afterIqbal = iqbal.nextElementSibling;
    // change the color to purple
    afterIqbal.style.color = 'purple';</script>
</body>
</html>

Komentar

Postingan populer dari blog ini

Template Aplikasi Web CRUD Sederhana dengan CodeIgniter

Instalasi library YAZ di PHP

An (Relatively) Easy Way for Installing Social Feed Manager on Mac OSX