如果我添加一个事件侦听器,我应该在文档级别添加它还是在文档树的下方添加它?
例如,假设我知道输入class="ExampleCss"
总是会在 div 中id="ExampleDiv"
。我应该使用:
$('#ExampleDiv').on(...);
或者
$(document).on(...);
?
我应该注意这方面的最佳做法吗?
提前致谢。
如果我添加一个事件侦听器,我应该在文档级别添加它还是在文档树的下方添加它?
例如,假设我知道输入class="ExampleCss"
总是会在 div 中id="ExampleDiv"
。我应该使用:
$('#ExampleDiv').on(...);
或者
$(document).on(...);
?
我应该注意这方面的最佳做法吗?
提前致谢。
最好使用更具体的选择器。当你像这样委托时,jQuery 必须沿着 DOM 树向下查找与委托选择器匹配的所有后代。显然document
拥有最多的后代。
使用更具体的选择器也更清晰,并且可以防止可能的错误(如果您.ExampleCss
不想触发此事件)。
使用更具体的选择器的唯一缺点是可能必须更改您以后要委托给的类的祖先。
最好通过 id 和/或类名来使用选择器。除了消除 jquery 遍历所有 dom 的额外时间浪费之外,它还将消除混淆,并保持您的代码可维护......
直接事件回调$(".aClass").on("click",function(){});
直接附加到元素,因此如果事件发生,则可以直接调用该回调。
对于委托事件回调$(element).on("click",".aClass", function() {});
,事件的事件回调附加到element
. 在附加事件回调时,selector
只是存储了参数,jquery 那时不会搜索匹配的元素。此选择器仅在元素接收到事件时使用(直接或当事件在 dom 中冒泡时)。然后 jquery 会检查作为事件起源的元素是否与选择器匹配。
因此,您应该使此选择器尽可能简单。测试.on("click", ".aClass", ...)
可以更快地完成,.on("click", ".foo div .bar .aClass", ...)
因为对于第一个,jQuery 只需要检查作为事件起源的元素是否具有.aClass
第二个 jQuery 的类,还需要测试其他条件。这就是尽可能具体的内容。
对于像click
,和其他很少触发的事件mousedown
,mouseup
您不会注意到性能影响。对于像这样在短时间间隔内调用的事件,在keypress
那里mousemove
使用委托可能不是最好的选择,因为在每个事件上,如果作为源的元素与选择器匹配,jquery 必须进行测试。(element
作为根使用)
另一件重要的事情是,并非所有事件都在 DOM 中冒泡。例如,带有或不冒泡scroll
的元素的事件(至少不在 chrome 中)。和其他事件也已知不会在某些浏览器或浏览器版本中冒泡。对于这些事件,不可能使用委托。overflow: scroll
overflow: auto
那么什么是更好的选择,这并不容易回答。如果您使用委托并且没有在明确的位置声明它们,则有时很难找出哪些元素具有回调。另一方面,如果您有一个非常动态的页面,您经常在其中添加或删除 DOM 中的元素,那么使用委托通常要容易得多,因为您不需要注意附加所有所需的事件回调到新添加的元素。
如果您想使用直接和委托,那么调用回调的顺序也有一些特殊之处:如果您使用 and 进行添加$(".aClass").on("click", ...)
并且$(document).on("click",".aClass", ...)
用户首先单击一个元素,.aClass
则直接附加的回调按附加的顺序调用,然后如果有匹配的委托回调按照它们附加的顺序调用,则事件正在冒泡到下一个侦听该事件的元素。然后事件继续冒泡,直到它到达文档。