2009-09-29 225 views
117

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

例如:

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

是否最后一个处理程序 “双赢”,或都将处理器上运行?

回答

141

两个处理程序将运行,jQuery的事件模型允许多个处理器在一个元件上,因此以后的处理不会覆盖旧的处理程序。

The handlers will execute in the order in which they were bound

+1

原生方式会发生什么?以及本地人如何知道如何删除特定的内容? – SuperUberDuper 2015-08-11 21:09:47

+1

根据DOM级别3(引用HTML 5规范),事件处理程序按其注册的顺序执行 - http://www.w3.org/TR/DOM-Level-3-Events/#event-phase和http://www.w3.org/TR/2014/REC-html5-20141028/webappapis.html#event-handler-attributes。事件处理程序可以通过传递已注册处理程序的引用来删除。 – 2015-08-11 23:26:50

+0

@RussCam如果同一个处理程序被绑定多次,只要说'jQuery('.btn')。on('click',handlerClick),会发生什么? '在不同的地方被调用,而不是实际上'.off'呢? – 2016-05-24 09:01:35

2

这两个处理程序都被调用。

您可能会想到inline event binding(例如"onclick=..."),其中一个很大的缺点是只能为事件设置一个处理程序。

jQuery的符合DOM Level 2 event registration model

的DOM事件模型允许多个事件在单个事件目标 听众的 登记。为了 实现这一目标,事件侦听器没有 不再存储为属性值

+0

你知道按什么顺序? – 2009-09-29 10:26:27

+0

@Rich:订单是官方未定义的。 – 2009-09-29 10:43:10

33

假设你有两个处理器,˚F,并希望确保他们在一个已知的和固定的顺序执行,然后只是它们封装:

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

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

+3

+1,函数内部的封装是要走的路。甚至可以在处理函数中包含更好的条件逻辑来控制触发的事件。 – 2009-09-29 10:49:41

+0

这在MHO中更好 – Sydwell 2012-09-28 16:19:05

+0

一组处理程序,它们的顺序是以编程方式确定的。 – 2014-03-25 05:54:42

8

你应该能够使用链接来执行顺序的事件,如:

$('#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

该代码和该文章都没有定义处理程序执行的顺序。是的,这是事件绑定*发生的顺序,但事件处理程序调用的顺序仍然是官方未定义的。 – 2009-09-29 10:58:26

+0

呃?那么“现在,当点击事件发生时,第一个事件处理程序将被调用,接着是第二个,然后是第三个。”不清楚? – anddoutoi 2009-09-29 11:00:35

+0

是的,我知道,官方的区域经济共同体没有定义和PPK已经证明,事件执行是随机的,但也许jQuery的已经修复了这个^^ – anddoutoi 2009-09-29 11:04:14

1

有一种解决方法可以确保一个处理程序在另一个处理程序之后发生:将第二个处理程序附加到包含元素并让该事件冒泡。在附加到容器的处理程序中,您可以查看event.target,如果它是您感兴趣的那个,请执行一些操作。

原油,也许,但它绝对应该工作。

2

使它成功使用2种方法:Stephan202的封装和多个事件侦听器。我有3个搜索选项卡,让我们定义它们的输入文本的id在Array:

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来测试它。

16

jQuery的.bind()火灾它必然顺序:

当一个事件到达的元素,绑定到该事件 类型的元件的所有处理程序被解雇。如果有多个处理程序 已注册,则它们将始终按它们的 范围内的顺序执行。在所有处理程序执行完毕后,事件继续沿着正常事件传播路径继续。

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

因为jQuery的其他功能(前.click())是.bind('click', handler)快捷方式,我猜想,他们还引发了它们绑定的顺序。