多个事件处理程序绑定到元素时的优先级

use*_*531 51 jquery

当多个事件处理程序绑定到一个元素时,如何确定首先触发哪一个?

<script> 
$(function(){
    $(".li").find('input').click(function(){alert('li>input');});
    $(".li").click(function(){alert('li');});
    $('input').click(function(){alert('input');});
});
</script>
</head>

<body>
<ul>
<li class="li"><input type="checkbox" /><span>Hello</span></li>
<li class="li"><input type="checkbox" /><span>Hello</span></li>
<li class="li"><input type="checkbox" /><span>Hello</span></li>
</ul>
</body>
Run Code Online (Sandbox Code Playgroud)

Dav*_*Lin 71

我想指出"先到先得"规则并不总是正确的,它还取决于你如何注册一个处理程序:

Handler1 - $(document).on('click', 'a', function....)
Handler2 - $('a').on('click', function....)
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,处理程序2始终在handler1之前调用.

看看这个小提琴:http://jsfiddle.net/MFec6/

  • @Maruccio造成这种情况的原因是因为冒泡.上例中的`Handler1`不是_actually_附加到`a`标签.相反,它附加到`document`.因此,执行Handler2,然后事件冒泡直到它命中`document`然后jQuery搜索`document`的事件委托以检查触发事件的元素是否与`on的第二个参数中提供的选择器匹配`for`Handler1`.实际上,它是"先到先得"的真实.冒泡完全是另一回事. (29认同)
  • 为什么这是行为? (3认同)
  • +1感谢您的回答.我一直在撞墙问题FCFS - 当然现在它是有道理的. (2认同)
  • @Swivel 如果有两个或多个处理程序附加到 #someID 的单击事件,那么它本质上是 FCFS,对吗? (2认同)
  • @ techie_28是的!:)这都是FCFS.事件冒泡[这里](http://javascript.info/tutorial/bubbling-and-capturing)有一些很棒的材料可以帮助你理解事件触发顺序.它是所有FCFS,从事件目标元素的处理程序开始,然后通过传播工作从DOM到根元素. (2认同)

jfr*_*d00 36

如果两个事件处理程序绑定到完全相同的对象,则它将是先到先服务.附加的第一个将首先执行.

但是,你的例子看起来有点不同.看起来您还有一个事件绑定到input对象,其他事件绑定到父li对象.在这种情况下,事件实际起源的那个(可能是input这种情况下的元素)将首先发生,然后事件将冒泡到父对象,它们将在以后发生.

如果你想停止冒泡到父母,你可以使用jQuery event.stopPropagation(),事件不会到达父母,也不会触发他们的事件处理程序.这看起来像这样:

$('input').click(function(e) {
    e.stopPropagation();
    alert('input');
});
Run Code Online (Sandbox Code Playgroud)

根据jQuery文档stopPropagation(),它不会停止同一对象上的其他事件处理程序,只会阻止父对象上的事件处理程序通常通过冒泡父树来获取事件.

你可以在这里看到不同之处:http://jsfiddle.net/jfriend00/L33aq/