Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 (Hidden or displayed anywhere on the page), with the same class name. The listener on the JS side would then run a function.

Here is what I am using for and ID based listener. It works well but I need to be able to have multiple buttons with the same class or name available. Although I have seen examples of this, I cannot get it to function properly.

function q1a1() {
var q1a1button = document.getElementById("q1answer1");
        if(q1a1button.addEventListener){
q1a1button.addEventListener("click", function() { q1answer1();}, false);
        } else if(q1a1button.attachEvent){
q1a1button.attachEvent("onclick", function() { q1answer1();});
}
};

if(window.addEventListener){
    window.addEventListener("load", q1a1, false);
        } else if(window.attachEvent){
    window.attachEvent("onload", q1a1);
        } else{
    document.addEventListener("load", q1a1, false);                
}

function q1answer1() {          

//DO SOME STUFF
                                            }

This also needs to work in as many versions of IE as possible. For single class handling I'm using querySelectorAll.

like image 955
user3460707 Avatar asked May 23 '14 17:05

user3460707


2 Answers

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);
}
else if (document.attachEvent) {
    document.attachEvent("onclick", handleClick);
}

function handleClick(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 event
    while (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;
    }
}

function doSomething(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.

like image 154
Greg Burghardt Avatar answered Oct 03 '22 14:10

Greg Burghardt


If you don't have jquery:

if (document.body.addEventListener){
    document.body.addEventListener('click',yourHandler,false);
}
else{
    document.body.attachEvent('onclick',yourHandler);//for IE
}

function yourHandler(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:

<div class="myClass">sample</div>
<div class="myClass">sample 2</div>

JS:

function theFuncToCall(event){
  //func code
}

$(document).on('click', '.myClass', theFuncToCall);
like image 31
carter Avatar answered Oct 03 '22 16:10

carter