是否允许多个元素都包含addEventListener?

时间:2012-10-30 15:44:13

标签: javascript event-handling delegation

我希望只有在点击了正确的按钮时才能调用指定的函数。

function callback(func){
func();
}

主要功能及其结果:

尝试A:

document.addEventListener('DOMContentLoaded', function () {

document.getElementById('num1').addEventListener('click', callback(function1));
document.getElementById('num2').addEventListener('click', callback(function2));

});

结果:打开页面并单击任何按钮将运行function1

尝试B:

document.addEventListener('click', function () {

document.getElementById('num1').addEventListener('click', callback(function1));
document.getElementById('num2').addEventListener('click', callback(function2));

});

结果:点击页面上的任意位置将运行function1

尝试C:

document.getElementById('num1').addEventListener('click', callback(function1));
document.getElementById('num2').addEventListener('click', callback(function2));

结果:打开页面并单击按钮将运行function1并重新加载页面

尝试D:

document.addEventListener('click', function () {

//The first ID doesn't exist
document.getElementById('imaginaryNum1').addEventListener('click', callback(function1));
document.getElementById('num1').addEventListener('click', callback(function1));
document.getElementById('num2').addEventListener('click', callback(function2));

});

结果:点击页面上的任意位置将运行function1

尝试E:

//The first ID doesn't exist
document.getElementById('imaginaryNum1').addEventListener('click', callback(function1));
document.getElementById('num1').addEventListener('click', callback(function1));
document.getElementById('num2').addEventListener('click', callback(function2));

结果:打开页面并单击按钮将运行function1并重新加载页面

2 个答案:

答案 0 :(得分:5)

当然,为什么不呢。但是,查看代码可能会更好地委派事件it's not that hard。基本上,在包含每个单独元素的dom中的级别上侦听所需的事件,并以这样的方式编写处理程序,以便检查触发事件的元素是否有意义,如果是这样的话:处理事件如果没有,就回来吧。你还错过了addEventListener期望的第三个参数:一个布尔值,表示你想要在捕捉阶段处理事件的天气,或冒泡阶段,read a couple of articles on quirksmode,特别是在distinct phases

我也注意到你使用处理程序函数做了一些奇怪的事情,你会遇到一些问题。基本上,addEventListener期望作为第二个参数是对函数的引用,您传递的是函数的返回值(在您的情况下未定义)。

function clickHandler(e)//accept event argument
{
    e = e || window.event;
    var target = e.target || e.srcElement;
    if (!target.id.match(/num[0-9]/))
    {//the clicked element doesn't have num1, num2, num3... as id, no need to handle this event
        return e;
    }
    //handle event. target is a reference to the clicked element
}
document.body.addEventListener('click',clickHandler,false);//<-- just the function name, no parentheses

这就是你所需要的,一个能够处理所有点击事件的听众。

以下是我发布的一些JS问题,处理事件委托,查看代码,阅读我链接的文章,你很快就会解决。
delegating the change event in IE - 棘手的 avoid mem-leaks in IE<9 with onload listener:我对问题的回答
IE中的Augmenting the event prototype&lt; 9使用委托

答案 1 :(得分:3)

callback会立即执行传递给它的函数 - 因此它永远不会传递给addEventListener - 而是传递undefined

.addEventListener('someEvent', callback(functionN), false)基本上是.addEventListener('someEvent', (function(){ functionN() })(), false)

更改为.addEventListener('someEvent', functionN, false),看看会发生什么 - 如果您仍然遇到错误,请查看网络浏览器的“脚本”面板,看看正在生成哪些错误。