Queryselector and Queryselectorall VS Getelementsbyclassname and Getelementbyid in JavaScript

querySelector and querySelectorAll vs getElementsByClassName and getElementById in JavaScript

I would like to know what exactly is the difference between querySelector and querySelectorAll against getElementsByClassName and getElementById?

The syntax and the browser support.

querySelector is more useful when you want to use more complex selectors.

e.g. All list items descended from an element that is a member of the foo class: .foo li

document.querySelector("#view:_id1:inputText1") it doesn't work. But writing document.getElementById("view:_id1:inputText1") works. Any ideas why?

The : character has special meaning inside a selector. You have to escape it. (The selector escape character has special meaning in a JS string too, so you have to escape that too).

document.querySelector("#view\\:_id1\\:inputText1")

Difference between getElementsByClassName and querySelectorAll?

querySelectorAll doesn't return live DOM elements. Subsequent changes to the structure of the underlying document won't be reflected in the NodeList object returned by querySelectorAll. This means that the object will instead contain a list of matching Element nodes that were in the document at the time the list was created.

getElementsByClassName returns live DOM elements. Any subsequent change made to those DOM elements would be reflected in the list.

What do querySelectorAll and getElementsBy* methods return?

Your getElementById code works since IDs have to be unique and thus the function always returns exactly one element (or null if none was found).

However, the methods
getElementsByClassName,
getElementsByName,
getElementsByTagName, and
getElementsByTagNameNS
return an iterable collection of elements.

The method names provide the hint: getElement implies singular, whereas getElements implies plural.

The method querySelector also returns a single element, and querySelectorAll returns an iterable collection.

The iterable collection can either be a NodeList or an HTMLCollection.

getElementsByName and querySelectorAll are both specified to return a NodeList; the other getElementsBy* methods are specified to return an HTMLCollection, but please note that some browser versions implement this differently.

Both of these collection types don’t offer the same properties that Elements, Nodes, or similar types offer; that’s why reading style off of document.getElements() fails.
In other words: a NodeList or an HTMLCollection doesn’t have a style; only an Element has a style.


These “array-like” collections are lists that contain zero or more elements, which you need to iterate over, in order to access them.
While you can iterate over them similarly to an array, note that they are different from Arrays.

In modern browsers, you can convert these iterables to a proper Array with Array.from; then you can use forEach and other Array methods, e.g. iteration methods:

Array.from(document.getElementsByClassName("myElement"))
.forEach((element) => element.style.size = "100px");

In old browsers that don’t support Array.from or the iteration methods, you can still use Array.prototype.slice.call.
Then you can iterate over it like you would with a real array:

var elements = Array.prototype.slice
.call(document.getElementsByClassName("myElement"));

for(var i = 0; i < elements.length; ++i){
elements[i].style.size = "100px";
}

You can also iterate over the NodeList or HTMLCollection itself, but be aware that in most circumstances, these collections are live (MDN docs, DOM spec), i.e. they are updated as the DOM changes.
So if you insert or remove elements as you loop, make sure to not accidentally skip over some elements or create an infinite loop.
MDN documentation should always note if a method returns a live collection or a static one.

For example, a NodeList offers some iteration methods such as forEach in modern browsers:

document.querySelectorAll(".myElement")
.forEach((element) => element.style.size = "100px");

A simple for loop can also be used:

var elements = document.getElementsByClassName("myElement");

for(var i = 0; i < elements.length; ++i){
elements[i].style.size = "100px";
}

Aside: .childNodes yields a live NodeList and .children yields a live HTMLCollection, so these two getters also need to be handled carefully.


There are some libraries like jQuery which make DOM querying a bit shorter and create a layer of abstraction over “one element” and “a collection of elements”:

$(".myElement").css("size", "100px");

getElementsByClassName vs querySelectorAll

Loop over the list backwards, then elements will vanish from the end (where you aren't looking any more).

for (var i = temp.length - 1; i >= 0; i--) { 
temp[i].className = "new_class";
}

Note, however, that IE 8 supports querySelectorAll but not getElementsByClassName, so you might want to prefer querySelectorAll for better browser support.


Alternatively, don't remove the existing class:

for (var i=0, max=temp.length; i<max; i++) {  
temp[i].className += " new_class";
}


Related Topics



Leave a reply



Submit