jQuery:同一事件有多个处理程序


137

如果将两个事件处理程序绑定到同一元素的同一事件会发生什么?

例如:

var elem = $("...")
elem.click(...);
elem.click(...);

最后一个处理程序是“胜利”,还是两个处理程序都将运行?

Answers:


168

这两个处理程序都将运行,jQuery事件模型在一个元素上允许多个处理程序,因此,较新的处理程序不会覆盖较旧的处理程序。

处理程序将按照绑定的顺序执行


1
本机方式会发生什么?本地人如何知道如何删除特定的?
SuperUberDuper 2015年

1
根据DOM Level 3(参考HTML 5规范),事件处理程序按照它们注册的顺序执行-w3.org/TR/DOM-Level-3-Events/#event-phasew3.org/TR/ 2014 / REC-html5-20141028 /…。可以通过将引用传递给已注册的处理程序来删除事件处理程序
Russ Cam

@RussCam如果将同一个处理程序绑定得更多,然后又一次jQuery('.btn').on('click',handlerClick);在不同的地方调用而实际上没有,.off那会发生什么呢?
techie_28 '16

请注意,对于jQueryUI widgetfactory小部件,如果将处理程序设置为选项,则情况并非如此。对于要调用的旧处理程序和新处理程序,您都需要使用bind方法。有关详细信息,请参阅本:learn.jquery.com/jquery-ui/widget-factory/...
迈克尔Scheper

@MichaelScheper可以随时编辑答案并使用其他信息进行更新
Russ Cam

36

假设您有两个处理程序fg,并希望确保它们以已知且固定的顺序执行,然后将它们封装起来:

$("...").click(function(event){
  f(event);
  g(event);
});

这样,(从jQuery的角度来看)只有一个处理程序,该处理程序以指定的顺序调用fg


3
+1,封装在函数内是必经之路。处理程序函数中甚至可以包含更好的条件逻辑,以控制触发的事件。
Gordon Potter,

处理程序的集合,其顺序以编程方式确定。
亚伦·布伦库什

17

jQuery的.bind()按照绑定的顺序触发

当事件到达元素时,将触发绑定到该事件类型的所有处理程序。如果注册了多个处理程序,则它们将始终按照绑定的顺序执行。执行完所有处理程序后,事件将沿正常事件传播路径继续。

资料来源:http//api.jquery.com/bind/

因为jQuery的其他功能(例如.click())是的快捷方式.bind('click', handler),所以我想它们也会按照绑定的顺序触发。


11

您应该能够使用链接顺序执行事件,例如:

$('#target')
  .bind('click',function(event) {
    alert('Hello!');
  })
  .bind('click',function(event) {
    alert('Hello again!');
  })
  .bind('click',function(event) {
    alert('Hello yet again!');
  });

我猜下面的代码正在做同样的事情

$('#target')
      .click(function(event) {
        alert('Hello!');
      })
      .click(function(event) {
        alert('Hello again!');
      })
      .click(function(event) {
        alert('Hello yet again!');
      });

来源:http : //www.peachpit.com/articles/article.aspx?p= 1371947& seqNum=3

TFM还说:

当事件到达元素时,将触发绑定到该事件类型的所有处理程序。如果注册了多个处理程序,则它们将始终按照绑定的顺序执行。执行完所有处理程序后,事件将沿正常事件传播路径继续。


1
该代码和该文章均未定义处理程序执行的顺序。是的,这是事件绑定将发生的顺序,但是事件处理程序被调用的顺序仍然是官方未定义的。

嗯?关于“现在,当单击事件发生时,将首先调用第一个事件处理程序,然后调用第二个,然后是第三个事件处理程序。” 还不清楚吗?
anddoutoi

是的,我知道官方文档未对此进行定义,而PPK已证明事件执行是随机的,但jQuery可能已修复了此^^
anddoutoi 2009年

啊,错过了那句话。实际上,作者被误导了。jQuery尚未“修复”此问题。由于规范未正式定义订单,因此技术上无需修复。

5
@CrescentFresh:很抱歉收到这么晚的答复,我只是看到了这个问题,但是我想请您指出要链接的地方,它是jQuery的官方文档,并且清楚地说:When an event reaches an element, all handlers bound to that event type for the element are fired. If there are multiple handlers registered, they will always execute in the order in which they were bound. After all handlers have executed, the event continues along the normal event propagation path.
Razort4x 2012年

2

两个处理程序都被调用。

您可能会想到内联事件绑定(例如"onclick=..."),其中最大的缺点是只能为一个事件设置一个处理程序。

jQuery符合DOM Level 2事件注册模型

DOM事件模型允许在单个EventTarget上注册多个事件侦听器。为此,事件侦听器不再存储为属性值


@Rich:订单未正式定义。

2

使用以下两种方法使其成功工作:Stephan202的封装和多个事件侦听器。我有3个搜索选项卡,让我们在数组中定义其输入文本ID:

var ids = new Array("searchtab1", "searchtab2", "searchtab3");

当searchtab1的内容更改时,我想更新searchtab2和searchtab3。是否通过这种方式进行封装:

for (var i in ids) {
    $("#" + ids[i]).change(function() {
        for (var j in ids) {
            if (this != ids[j]) {
                $("#" + ids[j]).val($(this).val());
            }
        }
    });
}

多个事件监听器:

for (var i in ids) {
    for (var j in ids) {
        if (ids[i] != ids[j]) {
            $("#" + ids[i]).change(function() {
                $("#" + ids[j]).val($(this).val());
            });
        }
    }
}

我喜欢这两种方法,但是程序员选择了封装,但是也可以使用多个事件侦听器。我们使用Chrome对其进行了测试。


1

有一种解决方法可确保一个处理程序接连发生:将第二个处理程序附加到包含元素,并使事件冒泡。在附加到容器的处理程序中,您可以查看event.target并执行一些您感兴趣的操作。

也许是粗略的,但绝对可以。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.