What is the difference between querySelectorAll() and getElementsByClassName()

Asked

Viewed 923 times

2

Apparently these two functions are similar, which one is more performative? Which one should I use? What is the difference between the two?

Document.querySelectorAll()

function funDOM() {
    var x = document.querySelectorAll(".example");
    var i;
    for (i = 0; i < x.length; i++) {
        x[i].style.backgroundColor = "red";
    }
}
<html>
<body onload="funDOM()">
    <div>
        Duvidas <span class="example">vermelhas</span>
    
    </div>
    <p class="example">vermelho</p>
    
    
</body>
</html>

Document.getElementsByClassName()

function funDOM() {
    var x = document.getElementsByClassName("example");
    var i;
    for (i = 0; i < x.length; i++) {
        x[i].style.backgroundColor = "red";
    }
}
<html>
<body onload="funDOM()">
    <div>
        Duvidas <span class="example">vermelhas</span>
    
    </div>
    <p class="example">vermelho</p>
    
    
</body>
</html>

Thanks in advance for your considerations.

  • 1

    The difference is that querySelectorAll can be used for selectors other than class only. And even being class can specify hierarchy for example using space or >

2 answers

2


getElementsByClassName returns DOM elements live and any subsequent change made to these DOM elements will be reflected in the list.

querySelectorAll does not return live DOM elements. Subsequent changes to the document structure will not be reflected in the returned Nodelist object. The element basically contains a list of nodes present in the document at the time it was created.

Suppose you have a class called bg-blue and this class is used in 5 different elements. Doing

var myElem = documento.getElementsByClassName("bg-blue");

The variable myElem would have the 5 elements that contain the class. To access a specific element you could do as follows.

var myElem = documento.getElementsByClassName("bg-blue")[0];

This way it will return the first DOM element with the class bg-blue

  • The two do not return a Nodelist with all elements?

  • When making a class modification using getElementsByClassName nodeList decrease, but querySelectorAll does not.

2

The main differences are basically two:

Example:

// buscar por elementos com a classe "abc"
let abcLiveList = document.getElementsByClassName('abc');
console.log('getElementsByClassName: ');
for (const e of abcLiveList) {
    console.log(`- ${e.innerText}`);
}
let abcFixedList = document.querySelectorAll('.abc');
console.log('querySelectorAll: ');
for (const e of abcFixedList) {
    console.log(`- ${e.innerText}`);
}

// atualizando o DOM (adicionar novo elemento)
let span = document.createElement('span');
span.classList.add('abc');
span.innerHTML = 'novo';
document.body.appendChild(span);

console.log('getElementsByClassName (atualizado com o novo elemento): ');
for (const e of abcLiveList) {
    console.log(`- ${e.innerText}`);
}
console.log('querySelectorAll (não é atualizado com o novo elemento): ');
for (const e of abcFixedList) {
    console.log(`- ${e.innerText}`);
}
<div class="abc">olá</div>
<p class="abc">tudo bem?</p>
<p>blá</p>

Note that in getElementsByClassName('abc') I passed the class name 'abc', already in querySelectorAll('.abc') the class name needed a point before ('.abc'), for this is the selector syntax to search for a class name.

See also that the list returned by getElementsByClassName changes as DOM changes: when adding a new element with the "abc" class, it becomes part of the list automatically. Already the list returned by querySelectorAll does not change, regardless of the changes made in the DOM (if I wanted to have the new element, I would need to do a new search).


Which one should I use?

It depends on what you need. Do you want the list to be updated as the DOM changes? Want to search only by class name or use some more complex criteria? (for example, only tags div with the class "abc" - in this case, querySelectorAll would be the most appropriate) - and so on. There is no right answer, it depends on the need.

As for being more performative, there are tests that say querySelectorAll is slower, but that shouldn’t be the only criterion. If it is a "very large" page with multiple searches being made, there may be some noticeable delay, but anyway, performance is something that should be tested case by case, you should not choose to use one or the other before testing (first choose what makes the most sense, and if you detect that this is the cause of bad performance, then you change).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.