JQuery: 同一事件的多个处理程序

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

例如:

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

是最后一个处理程序“赢”,还是两个处理程序都要运行?

124050 次浏览

两个处理器都会被调用。

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

JQuery 符合 DOM Level 2事件注册模型:

DOM 事件模型允许 多个事件的注册 单个 EventTarget 上的侦听器 实现这一点,事件侦听器是没有 作为属性值存储的时间更长

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

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

假设您有两个处理程序 F,并且希望确保它们以已知和固定的顺序执行,那么只需将它们封装起来:

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

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

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

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

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

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

也许很粗糙,但肯定能行。

使用以下两种方法使其成功工作: Stephan202的封装和多个事件侦听器。我有3个搜索选项卡,让我们在 Array 中定义它们的输入文本 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 来测试它。

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

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

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

因为 jQuery 的其他函数(例如。.click())是 .bind('click', handler)的快捷方式,我猜想它们也是按照它们被绑定的顺序被触发的。

Jquery 将执行这两个处理程序,因为它允许多个事件处理程序。 我已经创建了示例代码。您可以尝试它

小样