Reputation: 2105
I just started learning Javascript today and decided to start with practical examples, for example a toggle function.
This is what I've been ended with so far:
document.getElementsByClassName("toggle").addEventListener("click", function() {
if(this.classList.contains("toggled")) {
this.classList.remove("toggled")
}
else {
this.classList.add("toggled")
}
})
However it returns the error: document.getElementsByClassName(...).addEventListener is not a function. I figure that I havn't declared the function
correctly, but can't figure why. Here's a Codepen.
It's probably less of a problem as what I see it.
Upvotes: 1
Views: 3000
Reputation: 2731
The problem with that is that, document.getElementsByClassName()
returns array of DOM elements. To bind event to elements, you would have to iterate though each element, and bind event to it. Do it like this :
Convert the HTML collection before iterating :
[...document.getElementsByClassName("toggle")].forEach(function(item){
item.addEventListener("click", function() {
if(this.classList.contains("toggled")) {
this.classList.remove("toggled")
}
else {
this.classList.add("toggled")
}
})
});
OR
Using querySelectorAll()
:
document.querySelectorAll(".toggle").forEach(function(item){
item.addEventListener("click", function() {
if(this.classList.contains("toggled")) {
this.classList.remove("toggled")
}
else {
this.classList.add("toggled")
}
})
});
For detecting click on any element other than with class toggle
:
document.querySelector('body').addEventListener('click', function(event){
if(!event.target.classList.contains('toggle'){
//code to do
}
});
Upvotes: 1
Reputation: 1368
Please prefer querySelectorAll
over getElementsByClassName
.
In both cases you will give you an array of dom elements. So either you loop and bind the listener or take the certain index and it will work
const toggleButtons = document.querySelectorAll(".toggle")
if(toggleButton.length > 0) {
toggleButtons[0].addEventListener('click', function(event) {
if (this.classList.contains('toggled')) {
this.classList.remove('toggled');
} else {
this.classList.add('toggled');
}
})
}
Upvotes: 1
Reputation: 66
Simply add the index of element. In your case 0
document.getElementsByClassName("toggle")[0].addEventListener("click", function() {
if(this.classList.contains("toggled")) {
this.classList.remove("toggled")
}
else {
this.classList.add("toggled")
}
})
Upvotes: 1
Reputation: 1711
The method document.getElementsByClassName
(elements) returns an array of elements with this class. So when you want to access elements of the array you has to to something like:
let firstElement = document.getElementsByClassName("toggle")[0]
If you want to access exactly one element, use document.getElementById
or document.querySelector('.toggle')
Upvotes: 1