querySelectorAll() The Document method querySelectorAll() returns a static (not live) NodeList representing a list of the document's elements that match the specified group of selectors.
The querySelectorAll method returns an array-like object called a node list. These data structures are referred to as “Array-like”, because they appear as an array, but can not be used with array methods like map and forEach .
getElementsByTagName only selects elements based on their tag name. querySelectorAll can use any selector which gives it much more flexibility and power.
document. querySelector() will return the first element that matches the specified group of selectors. If no match is found 'null' is returned.
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 Array
s.
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";
}
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");
You are using a array as an object, the difference between getElementbyId
and
getElementsByClassName
is that:
getElementbyId
will return an Element object or null if no element with the ID is foundgetElementsByClassName
will return a live HTMLCollection, possibly of length 0 if no matching elements are foundThe
getElementsByClassName(classNames)
method takes a string that contains an unordered set of unique space-separated tokens representing classes. When called, the method must return a liveNodeList
object containing all the elements in the document that have all the classes specified in that argument, having obtained the classes by splitting a string on spaces. If there are no tokens specified in the argument, then the method must return an empty NodeList.
https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#getelementsbyclassname
The getElementById() method accesses the first element with the specified id.
https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById
in your code the lines:
1- document.getElementsByClassName('myElement').style.size = '100px';
will NOT work as expected, because the getElementByClassName
will return an array, and the array will NOT have the style
property, you can access each element
by iterating through them.
That's why the function getElementById
worked for you, this function will return the direct object. Therefore you will be able to access the style
property.
ES6 provides Array.from()
method, which creates a new Array instance from an array-like or iterable object.
let boxes = document.getElementsByClassName('box');
Array.from(boxes).forEach(v => v.style.background = 'green');
console.log(Array.from(boxes));
.box {
width: 50px;
height: 50px;
margin: 5px;
background: blue;
display: inline-block;
}
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
As you can see inside the code snippet, after using Array.from()
function you are then able to manipulate over each element.
The same solution using jQuery
.
$('.box').css({'background':'green'});
.box {
width: 50px;
height: 50px;
margin: 5px;
background: blue;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
The following description is taken from this page:
The getElementsByClassName() method returns a collection of all elements in the document with the specified class name, as a NodeList object.
The NodeList object represents a collection of nodes. The nodes can be accessed by index numbers. The index starts at 0.
Tip: You can use the length property of the NodeList object to determine the number of elements with a specified class name, then you can loop through all elements and extract the info you want.
So, as a parameter getElementsByClassName
would accept a class name.
If this is your HTML body:
<div id="first" class="menuItem"></div>
<div id="second" class="menuItem"></div>
<div id="third" class="menuItem"></div>
<div id="footer"></div>
then var menuItems = document.getElementsByClassName('menuItem')
would return a collection (not an array) of the 3 upper <div>
s, as they match the given class name.
You can then iterate over this nodes (<div>
s in this case) collection with:
for (var menuItemIndex = 0 ; menuItemIndex < menuItems.length ; menuItemIndex ++) {
var currentMenuItem = menuItems[menuItemIndex];
// do stuff with currentMenuItem as a node.
}
Please refer to this post for more on differences between elements and nodes.
In Other Words
document.querySelector()
selects only the first one element of the specified selector. So it doesn't spit out an array, it's a single value. Similar to document.getElementById()
which fetches ID-elements only, since IDs have to be unique.
document.querySelectorAll()
selects all elements with the specified selector and returns them in an array. Similar to document.getElementsByClassName()
for classes and document.getElementsByTagName()
tags only.
Why use querySelector?
It's used merely for the sole purpose of ease and brevity.
Why use getElement/sBy?*
Faster performance.
Why this performance difference?
Both ways of selection has the purpose of creating a NodeList for further use.
querySelectors generates a static NodeList with the selectors thus it must be first created from scratch.
getElement/sBy* immediately adapts the existing live NodeList of the current DOM.
So, when to use which method it's up to you/your project/your device.
Infos
Demo of all methods
NodeList Documentation
Performance Test
You could get a single element by running
document.querySelector('.myElement').style.size = '100px';
but it's going to work for the first element with class .myElement.
If you would like apply this for all elements with the class I suggest you to use
document.querySelectorAll('.myElement').forEach(function(element) {
element.style.size = '100px';
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With