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

How do I assign different event handlers to elements and their parent

本文关键字:元素 分配 程序 事件处理      更新时间:2023-09-26

假设我有如下结构:

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

如何为a、b和c分配不同的事件处理程序(比如onclick监听器)?当我为<ul>分配一个处理程序时,它将在单击任何<li>时被触发。

与其为列表中的每个元素设置一个单独的处理程序,不如在父级上使用一个事件侦听器,并使用事件委派来检测用户单击的元素的id

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

每当事件被触发时,它都会"冒泡"。这意味着它是在与它相关联的实际元素上调用的,但它也会为链中的每个父元素激发一次,一直到顶部。因此,在您的情况下,每当您单击bc时,a的事件也将触发。为了避免这种情况,你需要停止冒泡。

具体来说,在b和c的事件处理程序中,应该通过以下操作来停止事件冒泡:

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

大多数浏览器在事件上支持stopPropagation来结束冒泡。旧版本的IE使用cancelBubble属性。因此,以上内容应该是跨浏览器兼容的。

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

event.stopPropagation()

每个事件都会在DOM树中弹出(或者至少是"应该",因为有IE)。你可能想停止这种冒泡,看看本·李的回答。但还有更好的方法:

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

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

您可以使用它。

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

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