Buc*_*uck 157 javascript jquery jquery-selectors jquery-on
当我第一次学习jQuery时,我通常会附加这样的事件:
$('.my-widget a').click(function() {
$(this).toggleClass('active');
});
Run Code Online (Sandbox Code Playgroud)
在了解了有关选择器速度和事件委托的更多信息之后,我在几个地方读到"jQuery事件委托将使您的代码更快".所以我开始编写这样的代码:
$('.my-widget').on('click','a',function() {
$(this).toggleClass('active');
});
Run Code Online (Sandbox Code Playgroud)
这也是复制已弃用的.live()事件行为的推荐方法.这对我很重要,因为我的很多网站都在动态添加/删除小部件.上面的行为与.live()的行为完全不同,因为只有添加到现有容器".my-widget"的元素才会获得行为.如果我在代码运行后动态添加另一个html块,那么这些元素将不会获取绑定到它们的事件.像这样:
setTimeout(function() {
$('body').append('<div class="my-widget"><a>Click does nothing</a></div>');
}, 1000);
Run Code Online (Sandbox Code Playgroud)
我现在附上所有这样的事件:
$(document).on('click.my-widget-namespace', '.my-widget a', function() {
$(this).toggleClass('active');
});
Run Code Online (Sandbox Code Playgroud)
这似乎符合我的所有目标.(是的,因为某种原因它在IE中速度较慢,不知道为什么?)它很快,因为只有一个事件与单个元素相关联,而二级选择器仅在事件发生时进行评估(如果这里错误,请纠正我).命名空间非常棒,因为它可以更容易地切换事件监听器.
所以我开始认为jQuery事件应该始终绑定到$(document).
你有什么理由不想这样做吗?
这可算是最佳做法吗?如果没有,为什么?
如果您已经阅读了这一切,谢谢.我感谢任何/所有反馈/见解.
假设:
.on()
//至少1.7版的jQuery读数/例子:
jfr*_*d00 208
否 - 您不应该将所有委派的事件处理程序绑定到该document
对象.这可能是您可以创建的表现最差的场景.
首先,事件委托并不总能使您的代码更快.在某些情况下,它是有利的,在某些情况下不是.当您真正需要事件委派时以及从中受益时,您应该使用事件委派.否则,您应该将事件处理程序直接绑定到事件发生的对象,因为这通常会更有效.
其次,您不应该在文档级别绑定所有委派的事件.这正是为什么.live()
被弃用的原因,因为当你以这种方式绑定大量事件时,效率非常低.对于委托事件处理,将它们绑定到非动态的最近父节点会更有效.
第三,并非所有事件都有效,或者所有问题都可以通过授权来解决.例如,如果要拦截输入控件上的键事件并阻止将无效键输入到输入控件中,则无法通过委派事件处理来执行此操作,因为当事件冒泡到委派处理程序时,它已经由输入控件处理,影响该行为为时已晚.
以下是需要或有利的事件委托时间:
要了解这一点,需要了解jQuery如何委托事件处理程序工作.当你打这样的话:
$("#myParent").on('click', 'button.actionButton', myFn);
Run Code Online (Sandbox Code Playgroud)
它在#myParent
对象上安装通用的jQuery事件处理程序.当click事件冒泡到此委托事件处理程序时,jQuery必须遍历附加到此对象的委托事件处理程序列表,并查看该事件的原始元素是否与委派事件处理程序中的任何选择器匹配.
因为选择器可以公平地参与,这意味着jQuery必须解析每个选择器,然后将其与原始事件目标的特征进行比较,以查看它是否与每个选择器匹配.这不是一个便宜的操作.如果只有其中一个,这没什么大不了的,但是如果你把所有选择器放在文档对象上并且有数百个选择器可以与每个冒泡事件进行比较,那么这可能会严重影响事件处理性能.
因此,您需要设置委派的事件处理程序,以便委托事件处理程序尽可能接近目标对象.这意味着每个委托事件处理程序中的事件将会减少,从而提高性能.将所有委派事件放在文档对象上是最糟糕的性能,因为所有冒泡事件都必须通过所有委托事件处理程序并针对所有可能的委托事件选择器进行评估.这正是为什么.live()
被弃用的原因,因为这是做了什么.live()
,并且它被证明是非常低效的.
因此,要实现优化的性能:
事件委托是一种在元素实际存在于DOM之前编写处理程序的技术.此方法有其自身的缺点,只有在您有此类要求时才应使用.
什么时候应该使用事件委托?
为什么不应该使用事件委托?
PS:即使是动态内容,如果在内容插入DOM后绑定处理程序,也不必使用事件委托方法.(如果添加动态内容不经常删除/重新添加)