Skip to content Skip to sidebar Skip to footer

How Can I Add An Event Listener For Multiple Buttons With Same Class Name?

I'm building a decision tree in JavaScript. I do not have jQuery available to me for this project. I would like to be able to have buttons, placed anywhere in the decision tree (Hi

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

  1. 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;
        }
    }());
    
  2. Write your click handler

    functionclickHandler(e) {
        // do stuff
    }
    
  3. 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);
            }
        }
    }
    
  4. 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?"