JavaScript:具有相同类名的多个按钮的事件侦听器

JavaScript:具有相同类名的多个按钮的事件侦听器,javascript,listener,Javascript,Listener,我正在用JavaScript构建一个决策树。我没有可用于此项目的jQuery 我希望能够有按钮,放置在决策树的任何地方(隐藏或显示在页面上的任何地方),具有相同的类名。JS端的侦听器随后将运行一个函数 下面是我用于和基于ID的侦听器的内容。它工作得很好,但我需要能够有多个按钮与相同的类或名称可用。虽然我见过这样的例子,但我无法让它正常工作 function q1a1() { var q1a1button = document.getElementById("q1answer1");

我正在用JavaScript构建一个决策树。我没有可用于此项目的jQuery

我希望能够有按钮,放置在决策树的任何地方(隐藏或显示在页面上的任何地方),具有相同的类名。JS端的侦听器随后将运行一个函数

下面是我用于和基于ID的侦听器的内容。它工作得很好,但我需要能够有多个按钮与相同的类或名称可用。虽然我见过这样的例子,但我无法让它正常工作

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
                                            }

这也需要在尽可能多的IE版本中工作。对于单类处理,我使用querySelectorAll。

如果没有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
    }
}
如果使用jquery这样的跨浏览器库:

HTML:


你真正想要的是。在您的例子中,有按钮元素,我假设它们是
标记。现在,您想知道何时单击其中一个按钮,然后运行函数:

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
}
if(document.addEventListener){
document.addEventListener(“单击”,handleClick,false);
}
否则,如果(文件附件){
文件附件(“onclick”,handleClick);
}
函数handleClick(事件){
event=event | | window.event;
event.target=event.target | | event.src元素;
var元素=event.target;
//从事件目标爬上文档树
while(元素){
if(element.nodeName==“BUTTON”&&&/foo/.test(element.className)){
//用户单击了或单击了
//使用名为“foo”的类名
剂量测定(元素);
打破
}
element=element.parentNode;
}
}
功能剂量测量(按钮){
//用按钮做点什么
}
在页面上出现
..
元素的任何位置,单击该元素或其中的任何HTML标记,都将运行
doSomething
功能

更新:由于使用了事件委派,因此在文档对象上只注册了一个单击处理程序。如果由于AJAX调用而创建了更多的
,则不必在这些新的
上注册单击处理程序,因为我们利用了从用户单击的元素到文档对象本身冒出的单击事件。

var buttons=document.querySelectorAll(.MyClassName”);
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
        });
    };
};
变量i=0,长度=buttons.length; 对于(i;i
这个答案有点过头了,但它应该向您展示了如何以“现代”的方式构造代码,即使您仍然以旧浏览器为目标

var listen = (function () { // will return the handler for use in unlisten
    if (window.addEventHandler) {
        return function (node, type, handler) {
            node.addEventListener(type, handler);
            return handler;
        };
    } else if (window.attachEvent) {
        return function (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 {
        throw new Error('Events not supported in this environment');
        // or
     // return function ... node['on' + type] = function () { ... };
    }
}());
  • 编写代码以添加事件侦听器,使新旧浏览器之间的差异最小

    var listen = (function () { // will return the handler for use in unlisten
        if (window.addEventHandler) {
            return function (node, type, handler) {
                node.addEventListener(type, handler);
                return handler;
            };
        } else if (window.attachEvent) {
            return function (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 {
            throw new Error('Events not supported in this environment');
            // or
         // return function ... node['on' + type] = function () { ... };
        }
    }());
    
    如果你也想要相反的

    var unlisten = (function () { // use handler given by listen
        if (window.removeEventListener) {
            return function (node, type, handler) {
                node.removeEventListener(type, handler);
            };
        } else if (window.detachEvent) {
            return function (node, type, handler) {
                node.detachEvent('on' + type, handler);
            };
        } else {
            throw new Error('Events not supported in this environment');
            // or
         // return function ... node['on' + type] = null;
        }
    }());
    
  • 编写你的点击处理程序

    function clickHandler(e) {
        // do stuff
    }
    
  • 将单击处理程序包装在一个函数中,以仅选择具有正确类的按钮上的单击

    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);
            }
        }
    }
    

  • 编写事件委派函数的更简单方法是将其添加到按钮的容器中吗?比如说,

    // Select Container Element
    const questionContainer = document.querySelector(".container");
    
    // Listen For Clicks Within Container
    questionContainer.onclick = function (event) {
        // Prevent default behavior of button
        event.preventDefault();
    
        // Store Target Element In Variable
        const element = event.target;
    
        // If Target Element Is a Button
        if (element.nodeName === 'BUTTON') {
            // Event Code
        }
    }
    

    只需使用querySelectorAll()遍历该类的元素,或多或少地围绕已有的代码包装该循环。您还可以将单个事件附加到主体,并查看(e.target | | e.srcElement).className以决定如何在调用时处理事件。querySelectorAll在ie8中工作。如果你需要支持低于这个标准的东西,我为你感到抱歉。只需遍历元素数组,为每个元素添加一个事件侦听器。jQuery在此组织内不可用。(我无法使用它)因此产生了挫折感和新的学习曲线。:)必须链接到:)jQuery的
    on
    方法非常方便,但对于我们这些没有jQuery或不想使用它的人来说,我写道,它利用了HTML5数据-*属性。它允许您将行为、标记和样式完全解耦。@Greg Burghardt如果您希望单击的按钮颜色改变,我们如何在没有唯一id或类名的情况下实现这一点?我正在寻找提取事件目标的方法。你的代码告诉了我怎么做。谢谢。这非常有用。
    var h = listen(document, 'click', wrappedClickHandler);
    // .. later, if desired
    unlisten(document, 'click', h);
    
    // Select Container Element
    const questionContainer = document.querySelector(".container");
    
    // Listen For Clicks Within Container
    questionContainer.onclick = function (event) {
        // Prevent default behavior of button
        event.preventDefault();
    
        // Store Target Element In Variable
        const element = event.target;
    
        // If Target Element Is a Button
        if (element.nodeName === 'BUTTON') {
            // Event Code
        }
    }