Problem
I’m currently attempting to develop some JavaScript in order to obtain the attribute of the clicked class. I understand that the proper way to achieve this is to utilize an event listener. The following is my code:
var classname = document.getElementsByClassName("classname");
var myFunction = function() {
var attribute = this.getAttribute("data-myattribute");
alert(attribute);
};
classname.addEventListener('click', myFunction(), false);
I was expecting an alert box to appear every time I clicked on one of the classes, informing me of the attribute, but this does not appear to be the case. Could someone please assist me?
(Note: I could accomplish this fairly easily with jQuery, but I don’t want to.)
Asked by 30secondstosam
Solution #1
This ought to work. getElementsByClassName provides an array of elements matching the criteria as an Array-like object(see edit).
var elements = document.getElementsByClassName("classname");
var myFunction = function() {
var attribute = this.getAttribute("data-myattribute");
alert(attribute);
};
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', myFunction, false);
}
jQuery takes care of the looping for you, which you would otherwise have to accomplish in plain JavaScript.
Replace your last line with: if you have ES6 support.
Array.from(elements).forEach(function(element) {
element.addEventListener('click', myFunction);
});
Note that older browsers (such as Internet Explorer 6, 7, and 8) do not support getElementsByClassName and hence return undefined.
Correction
In most browsers, getElementsByClassName does not return an array, but rather an HTMLCollection or a NodeList (Mozilla ref). Both of these types are Array-Like (that is, they have a length property and the objects can be accessed by their index), but they aren’t exactly Arrays or inherited from them (meaning other methods that can be performed on an Array cannot be performed on these types).
Thanks to user @Nemo for bringing this to my attention and forcing me to delve further to properly comprehend.
Answered by Anudeep Bulla
Solution #2
It’s as simple as this with current JavaScript:
Answered by V. Sambor
Solution #3
* This was changed to allow the events to be triggered by children of the target class. Details can be found at the bottom of the answer.
An alternative solution for adding an event listener to a class with frequently added and removed items. This is based on jQuery’s on function, which allows you to specify a selector for a child element to which the event should listen.
var base = document.querySelector('#base'); // the container for the variable content
var selector = '.card'; // any css selector for children
base.addEventListener('click', function(event) {
// find the closest parent of the event target that
// matches the selector
var closest = event.target.closest(selector);
if (closest && base.contains(closest)) {
// handle class event
}
});
Fiddle: https://jsfiddle.net/u6oje7af/94/
This will listen for clicks on the base element’s children and handle the class event if the target of the click has a parent that matches the selector. You can add and remove items as needed without having to add additional click listeners to each one. This, like the jQuery functionality, will catch them all, even for elements added after this listener was added (which I imagine is somewhat similar under the hood).
This is dependent on the events propagating, thus if you stopPropagation on the event elsewhere, it might not function. Also, it appears that the nearest function has some IE compatibility difficulties (what doesn’t?).
If you need to perform this type of activity repeatedly, such as listening, this might be turned into a function.
function addChildEventListener(base, eventName, selector, handler) {
base.addEventListener(eventName, function(event) {
var closest = event.target.closest(selector);
if (closest && base.contains(closest)) {
// passes the event to the handler and sets `this`
// in the handler as the closest parent matching the
// selector from the target element of the event
handler.call(closest, event);
}
});
}
========================================= EDIT: This post initially used the matches function on the event target for DOM components, but this limited event targets to the direct class only. It has been changed to utilize the nearest function instead, allowing events to be triggered by children of the chosen class as well. The original matches code can be seen at https://jsfiddle.net/u6oje7af/23/ on the original fiddle.
Answered by obermillerk
Solution #4
You can use the following code:
document.body.addEventListener('click', function (evt) {
if (evt.target.className === 'databox') {
alert(this)
}
}, false);
Answered by Rajat kumar
Solution #5
To add the eventListener, use querySelectorAll to select all the classes and cycle through them. If the class name is present, the if condition is true.
const arrClass = document.querySelectorAll(".className");
for (let i of arrClass) {
i.addEventListener("click", (e) => {
if (e.target.classList.contains("className")) {
console.log("Perfrom Action")
}
})
}
Answered by Bhargav
Post is based on https://stackoverflow.com/questions/19655189/javascript-click-event-listener-on-class