如何为元素及其父级分配不同的事件处理程序

时间:2012-03-19 09:29:53

标签: javascript html dom javascript-events

说我的结构如下:

<ul id="a">text
    <li id="b">text</li>
    <li id="c">text</li>
</ul>

如何为a,b和c分配不同的事件处理程序(比如onclick listener)?当我将处理程序分配给<ul>时,会在点击任何<li>时触发。

5 个答案:

答案 0 :(得分:3)

而不是为列表中的每个元素设置单个处理程序,最好在父级上使用单个事件侦听器,并使用事件委托检测哪个是用户单击的元素的id

$('ul').on('click', function(evt) {
   id = evt.target.id;
   switch (id) {
      "a" : ... break;
      "b" : ... break;
      "c" : ... break;
      default: ... ;
   }   

});

答案 1 :(得分:2)

每当一个事件被触发时,它就会“起泡”。这意味着它在与它相关联的实际元素上被调用,但它也为链中的每个父元素一直触发到顶部。因此,在您的情况下,只要您点击bc,该事件也会a触发。为避免这种情况,您需要停止冒泡。

具体来说,在b和c的事件处理程序中,你应该通过这样做来停止事件冒泡:

if (event.stopPropagation) event.stopPropagation();
else event.cancelBubble = true;

大多数浏览器都支持事件stopPropagation以结束冒泡。旧版本的IE使用cancelBubble属性。所以上面应该是跨浏览器兼容的。

我知道你没有指定jQuery,但由于它如此受欢迎,值得注意的是,如果你使用jQuery,这个条件隐藏在框架后面,所以你可以这样做:

event.stopPropagation()

答案 2 :(得分:1)

每个事件都会在DOM树中冒泡(或者至少“应该”,因为有IE)。您可能想停止冒泡,请参阅Ben Lee's answer。但有更好的方法:

只需检查触发您的侦听器的事件是否针对您正在观看的元素被触发。然后执行你的处理程序,或者转义。

document.getElementById("a").addEventListener("click", function(e) {
    var a = e.currentTarget; // reference to #a
    var t = e.target; // this may be #b or #c or any of their children - or not
    if (a != t)
        return;
    // else
    // do what you wanted to do
}, false);

答案 3 :(得分:0)

你可以使用它。

$('ul li#a').click(function(){
//some thing here...
});
$('ul li#b').click(function(){
//some thing here...
});

答案 4 :(得分:0)

我的一个项目中也遇到了同样的问题。我所做的是首先声明一个全局变量(用于标记目的,默认值为false)。然后我触发了所有子节点上的onmouseover和onmouseout事件,并且每当光标在子节点上时将标志值更改为true(并且每当它离开子节点时将其恢复为false)。因此,在声明父级的onclick函数时,只需输入一个条件来检查flag的值。