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 methodsgetElementsByClassName
,getElementsByName
,getElementsByTagName
, andgetElementsByTagNameNS
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";
}
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");
What type of data does querySelectorAll return?
The Element method
querySelectorAll()
returns a static (not live) NodeList representing a list of the document's elements that match the specified group of selectors.
For the differences please visit: Difference between HTMLCollection, NodeLists, and arrays of objects
You can use Spread syntax to make that as an array:
var obj1 = { fname: "Mirajul", lname: "Momin", age: 24};console.log(obj1.length);var paraList = [...document.querySelectorAll("p")];console.log(paraList.length);console.log(Array.isArray(paraList));
<p>This is paragraph one</p><p>This is paragraph two</p><p>This is paragraph three</p><p>This is paragraph four</p>
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")
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";
}
JavaScript why cannot select the elements
According to mdn:
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.
It is like the document.getElementsByClassName
which return you a nodelist and you have to specify the index or you could use document.querySelector
const content = document.querySelectorAll('.test');
content[0].classList.add('hide-content');
.Content {
width: 180px;
height: 90px;
background-color: green;
}
.hide-content {
display: none
}
<div class="Content"></div>
<div class="Content test"></div>
<div class="Content test"></div>
Can't get getElementsByClassName or querySelectorAll to work
Document.querySelectorAll()
returns a NodeList
, which you can think of like an array of elements. In order to hide each of them, you have to iterate through the list and hide each element individually.
Read more about Document.querySelectorAll()
: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
function toggleBoxVisibility() {
if (document.querySelector(".check").checked) {
document.querySelectorAll(".box").forEach(box => {
box.style.opacity = '0';
});
} else {
document.querySelectorAll(".box").forEach(box => {
box.style.opacity = '1';
});
}
}
.box {
background: lightblue;
width: 200px;
height: 200px;
display: inline-block;
}
<input type="checkbox" class="check" onclick="toggleBoxVisibility()">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
How to get clicked element's text using querySelectorAll and addEventListener in javascript
document.querySelectorAll() returns multiple items. Maybe you want to add a listener to each item.
var elements = document.querySelectorAll(".key");
elements.forEach(element => {
element.addEventListener("click", function(e) {
console.log(e.target.innerText);
});
});
<button class="key">Hello</button>
<button class="key">Hello2</button>
<button class="key">Hello3</button>
I want to change a variable in html by js but am not sure how to do it
To change the actual attribute of data-theme, use:
document.documentElement.setAttribute('data-theme', 'dark');
But of course you need to define what element you're going to change. Here, I cannot recommend what you should do as it all depends on what you're trying to do. You can use id, class or queryselectors. Even use triggers such as onclick() etc. But..
But an id example here:
First add an id to your , in this case let's call it "change-me".
Then:
document.getElementById("change-me").setAttribute('data-theme', 'dark');
To use queryselector, do this:
document.querySelector('[data-theme="original"]').setAttribute("data-theme", "dark")
Related Topics
How to Automatically Reload a Web Page At a Certain Time
How to Get the Background Color of an HTML Element
How to Simulate a Mouseover in Pure JavaScript That Activates the CSS ":Hover"
How to Add CSS With JavaScript
How to Refer to JavaScript Variables Across Webpages in a Browser Session
Html5 Dragleave Fired When Hovering a Child Element
Select All Elements With a "Data-Xxx" Attribute Without Using Jquery
Detecting the System Dpi/Ppi from Js/Css
Dynamically Resizing Image-Maps and Images
How to Use CSS (And JavaScript) to Create a Blurred, "Frosted" Background
Forcing Web-Site to Show in Landscape Mode Only
Changing a CSS Rule-Set from JavaScript
How to Make a Div Stick to the Top of the Screen Once It's Been Scrolled To
Why Is Using "For...In" For Array Iteration a Bad Idea
Jquery Ajax Post Example With PHP