How Can I Add An Event Listener For Multiple Buttons With Same Class Name?
Solution 1:
What you are really looking for is JavaScript Event Delegation. In your case, you have BUTTON elements, which I'm going to assume are <button>
tags. Now you want to know when one of those buttons was clicked and then run a function:
if (document.addEventListener) {
document.addEventListener("click", handleClick, false);
}
elseif (document.attachEvent) {
document.attachEvent("onclick", handleClick);
}
functionhandleClick(event) {
event = event || window.event;
event.target = event.target || event.srcElement;
var element = event.target;
// Climb up the document tree from the target of the eventwhile (element) {
if (element.nodeName === "BUTTON" && /foo/.test(element.className)) {
// The user clicked on a <button> or clicked on an element inside a <button>// with a class name called "foo"doSomething(element);
break;
}
element = element.parentNode;
}
}
functiondoSomething(button) {
// do something with button
}
Anywhere on the page that a <button class="foo">...</button>
element appears, clicking it, or any HTML tag inside of it, will run the doSomething
function.
Update: Since Event Delegation is used, only a single click handler is registered on the document object. If more <button>
s are created as a result of an AJAX call, you don't have to register click handlers on those new <button>
s since we take advantage of the click event bubbling up from the element the user clicked on to the document object itself.
Solution 2:
If you don't have jquery:
if (document.body.addEventListener){
document.body.addEventListener('click',yourHandler,false);
}
else{
document.body.attachEvent('onclick',yourHandler);//for IE
}
functionyourHandler(e){
e = e || window.event;
var target = e.target || e.srcElement;
if (target.className.match(/keyword/))
{
//an element with the keyword Class was clicked
}
}
If you use a cross browser library like jquery:
HTML:
<divclass="myClass">sample</div><divclass="myClass">sample 2</div>
JS:
functiontheFuncToCall(event){
//func code
}
$(document).on('click', '.myClass', theFuncToCall);
Solution 3:
var buttons = document.querySelectorAll(".MyClassName");
var i = 0, length = buttons.length;
for (i; i < length; i++) {
if (document.addEventListener) {
buttons[i].addEventListener("click", function() {
// use keyword this to target clicked button
});
} else {
buttons[i].attachEvent("onclick", function() {
// use buttons[i] to target clicked button
});
};
};
Solution 4:
This answer is a bit overkill, but it should show you ways you could structure your code in a "modern" way even if you're still targeting old browsers
Write code to add event listeners so there is minimal difference between new and old browsers
var listen = (function () { // will return the handler for use in unlistenif (window.addEventHandler) { returnfunction (node, type, handler) { node.addEventListener(type, handler); return handler; }; } elseif (window.attachEvent) { returnfunction (node, type, handler) { var fn = function (e) { if (!e) { e = window.event; } if (!e.target && e.srcElement) { e.target = e.srcElement; } return handler.call(this, e); }; node.attachEvent('on' + type, fn); return fn; }; } else { thrownewError('Events not supported in this environment'); // or// return function ... node['on' + type] = function () { ... }; } }());
and if you'd like the reverse, too
var unlisten = (function () { // use handler given by listenif (window.removeEventListener) { returnfunction (node, type, handler) { node.removeEventListener(type, handler); }; } elseif (window.detachEvent) { returnfunction (node, type, handler) { node.detachEvent('on' + type, handler); }; } else { thrownewError('Events not supported in this environment'); // or// return function ... node['on' + type] = null; } }());
Write your click handler
functionclickHandler(e) { // do stuff }
Wrap your click handler in a function to choose only clicks on buttons with the right class
function wrappedClickHandler(e) { var tokens, i; if (e.target.tagName !== 'INPUT' && e.target.tagName !== 'BUTTON') { return; } tokens = (e.target.className || '').split(' '); for (i = 0; i < tokens.length; ++i) { if (tokens[i] === 'theClassTokenWeWant') { return clickHandler.call(this, e); // or// return clickHandler.call(e.target, e); } } }
Add this as a listener to a common ancestor node
var h = listen(document, 'click', wrappedClickHandler); // .. later, if desiredunlisten(document, 'click', h);
Solution 5:
Would the simpler way of writing the event delegation function be to add it to the container of the buttons? For example,
// Select Container Elementconst questionContainer = document.querySelector(".container");
// Listen For Clicks Within Container
questionContainer.onclick = function (event) {
// Prevent default behavior of buttonevent.preventDefault();
// Store Target Element In Variableconst element = event.target;
// If Target Element Is a Buttonif (element.nodeName === 'BUTTON') {
// Event Code
}
}
Post a Comment for "How Can I Add An Event Listener For Multiple Buttons With Same Class Name?"