这两种不同的jQuery语句的性能和处理有何不同:
排名第一:
$('#selector1, #selector2, .class1').on('click', function () {
//stuff
});
第二名:
$(document).on('click', '#selector1, #selector2, .class1', function () {
//stuff
});
我知道一个人做代表团而另一个人没有代表团。
但这意味着什么?
点击'#selector1, #selector2, .class1'
时,不要两者都采取某种行动吗?
最后,是不是一样?
答案 0 :(得分:8)
Number One会在执行该语句时将click
事件挂钩到存在的元素上。例如,处理程序直接挂钩到执行该调用时匹配的实际元素。
第二个会将click
事件挂钩到文档上,并且在收到任何点击后,将检查实际点击的元素是否与任何给定的选择器匹配,如果是,则触发处理程序。这是事件委托而不是直接连接。
所以这意味着几件事:
click
这样的冒泡事件才能与第二号一起工作(因为它依赖于将DOM冒泡到文档级别的事件)。有时候使用直接挂钩的处理程序会更好,而事件委派(通常使用比document
更集中的东西)的时候更好。通常,它们之间的分界线是一个判断调用,但是例如,如果你想响应表行的点击,你可能最好用click
元素挂钩table
事件。 tr
选择器,而不是附加每个表行的click
事件,尤其是在动态更新表时。然而,如果你有一个独特的按钮,当你正在连接你的处理程序时你知道它存在于DOM中,并且当你想要在点击该按钮(但不是其他任何东西)时触发特定的函数,直接处理程序可能更有意义。
以下是一个示例(live copy):
HTML:
<p>Click me</p>
JavaScript的:
jQuery(function($) {
$('p').on('click', function() {
display("Directly-attached handler fired. Click this paragraph and note the difference in what happens compared to when you click the 'click me' paragraph.");
});
$(document).on('click', 'p', function() {
display("Delegated handler fired.");
});
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
});
请注意,当您单击“单击我”段落时,您会在文档中添加两个新段落,其中一个是第一个on
调用的结果,另一个是第二个调用的结果。但请注意,如果您单击这两个新段落中的任何一个,则仅会从第二个on
调用(委派的一个)中查看处理程序,而不是第一个。那是因为当你连接第一个处理程序时,那些段落不存在。
答案 1 :(得分:5)
on()
方法为jQuery对象匹配的每个元素附加一个事件处理程序。如果将可选选择器传递给on()
方法,则只有在该元素的后代发生事件时才会触发处理程序。
因此,第一个示例将附加多个事件处理程序,因为jQuery对象包含3个元素。但是,第二个示例将附加一个事件处理程序,它将处理所有'#selector1, #selector2, .class1'
的
显然,如果匹配了许多元素,则第一个处于性能劣势(因为绑定了多个事件处理程序,与第二个示例中附加的单个事件处理程序相比)。
对于少量对象,选择第一个示例优先于微优化。但是,如果你有很多元素(列表项,表中的行),你应该认真考虑使用第二个例子。
因为on()
将处理程序附加到jQuery对象匹配的每个元素,所以不能将处理程序直接附加到尚未包含在DOM中的元素(例如,如果您希望通过编程方式添加元素代码或通过AJAX)。这就是将选择器作为参数提供给on()
的能力变得非常非常有用;这允许您将事件处理程序附加到当前在DOM中的元素,但是它将处理触发DOM中尚未但与您提供的选择器匹配的元素的事件
换句话说,在第一个示例中,jQuery将事件处理程序附加到与#selector1, #selector2, .class1
选择器匹配的所有元素;所以会遗漏尚未在DOM中注册的所有元素。
另一方面,如果您使用第二个示例,jQuery会将事件处理程序附加到与document
选择器匹配的所有元素(例如单个Document
元素),并为其附加处理程序如果它收到的事件来自选择器#selector1, #selector2, .class1
匹配的元素,它将触发;这有利于所有未来的#selector1, #selector2, .class1
元素。
你可以在这里看到这个; http://jsfiddle.net/kntR7/
因为第二个绑定到document
,所以接受同一事件的处理程序的任何元素都将在之前接收处理程序(因为document
是通过接收处理程序的最后一个位置事件传播),因此,如果它选择使用event.stopPropagation()
或event.stopImmediatePropagation()
取消事件,则永远不会到达处理程序。
你可以在这里看到这个; http://jsfiddle.net/mkNyU/
答案 2 :(得分:1)
对于熟悉1.7之前语法的人,以下是on
的使用方法:
//bind syntax
$(selector).on(event, callback);
$(selector).bind(event, callback);
//delegate syntax
$(parent).on(event, selector, callback);
$(selector).delegate(selector, event, callback);
//live syntax
$(document).on(event, selector, callback);
$(selector).live(event, callback);
因此,您的第一行($('#selector1, #selector2, .class1').on('click', function)
)是bind
格式,用于将事件附加到现有元素。
您的第二行($(document).on('click', '#selector1, #selector2, .class1', function)
)是一种live
格式,用于在事件发生时将事件附加到与选择器匹配的任何元素,无论绑定时元素是否存在于dom中
答案 3 :(得分:0)
第一个绑定3+事件处理程序(每个元素一个),一旦元素被替换就会丢失。如果元素尚不存在,第一个将失败。
第二个绑定1个事件处理程序(一个到document
)除非您明确删除它,否则永远不会丢失。一旦在此处调用处理程序,该事件就已传播到document
。无论何时单击页面上的任何位置,jQuery都会在内部检查它是否在与您提供的选择器匹配的任何元素上,并触发您提供的处理程序。仅当事件传播到document
并且未在较低级别元素处停止时才会这样。
第二个可以在文档就绪之前绑定,即使元素不存在它仍然可以工作。