为了账号安全,请及时绑定邮箱和手机立即绑定

是否应该将所有jQuery事件绑定到$(Document)?

是否应该将所有jQuery事件绑定到$(Document)?

沧海一幻觉 2019-06-03 16:06:46
是否应该将所有jQuery事件绑定到$(Document)?这是从哪里来的当我第一次学习jQuery时,我通常会附加这样的事件:$('.my-widget a').click(function() {     $(this).toggleClass('active');});在了解了更多关于选择器速度和事件委派的信息之后,我在几个地方读到了“jQuery事件委托将使您的代码更快”。所以我开始写这样的代码:$('.my-widget').on('click','a',function() {     $(this).toggleClass('active');});这也是复制被弃用的.live()事件的行为的推荐方法。这对我来说很重要,因为我的很多站点总是动态地添加/删除小部件。不过,上面的行为并不完全像.live(),因为只有添加到已有容器‘.my-widget’中的元素才会得到行为。如果在代码运行后动态添加另一个html块,这些元素将不会得到绑定到它们的事件。就像这样:setTimeout(function() {     $('body').append('<div class="my-widget"><a>Click does nothing</a></div>');}, 1000);我想达到的目标是:.live()/的旧行为意味着将事件附加到尚未存在的元素.on()的好处绑定事件的最快性能管理事件的简单方法现附上以下所有事件:$(document).on('click.my-widget-namespace', '.my-widget a', function() {     $(this).toggleClass('active');});似乎满足了我所有的目标。(是的,由于某种原因,IE的速度比较慢,不知道为什么?)它的速度很快,因为只有单个事件被绑定到一个单数元素,而次要选择器只有在事件发生时才会被评估(如果这里出错,请更正我)。命名空间很棒,因为它使切换事件侦听器变得更容易。我的解决办法/问题因此,我开始认为jQuery事件应该始终绑定到$(文档)。你有什么理由不想这么做吗?这是否可以被视为最佳做法?如果没有,为什么?如果你读过这篇文章,谢谢。我感谢任何/所有的反馈/见解。假设:使用支持.on()/至少1.7版您希望将事件添加到动态添加的内容中。阅读资料/例子:http:/24 ways.org/2011/you-jQuery-Now-with-lesshttp:/brandonaaron.net/blog/2010/03/4/Event-委托-with-jQueryhttp:/www.jason想克博爱网/游乐场/航速/速.htmlhttp://api.jquery.com/on/
查看完整描述

2 回答

?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

否-您不应将所有委托的事件处理程序绑定到document对象。这可能是您所能创建的最糟糕的执行场景。

首先,事件委托并不总是使代码更快。在某些情况下,它是有利的,在某些情况下不是。当您实际需要事件委托并从中受益时,您应该使用事件委托。否则,您应该将事件处理程序直接绑定到事件发生的对象,因为这通常会更有效。

其次,不应在文档级别绑定所有委托事件。这就是为什么.live()被否决,因为这是非常低效的,当你有很多事件这样绑定。对于委托事件处理,将它们绑定到非动态的最接近的父级更有效。

第三,并不是所有的事件都可以通过委托解决所有的问题。例如,如果您想拦截输入控件上的键事件并阻止无效键被输入到输入控件中,则不能使用委托的事件处理来执行此操作,因为当事件冒泡到委托处理程序时,输入控件已经对其进行了处理,而且影响该行为为时已晚。

在这里,事件委托是必需的或有利的:

  • 当您捕获事件的对象被动态创建/删除时,您仍然希望捕获事件,而不必每次创建新事件时都显式地重新绑定事件处理程序。
  • 当您有很多对象都需要完全相同的事件处理程序时(其中很多对象至少是数百个)。在这种情况下,在安装时绑定一个委托事件处理程序可能比绑定数百个或更多直接事件处理程序更有效。注意,与直接事件处理程序相比,在运行时委托事件处理总是效率较低.
  • 当您试图捕获(文档中较高级别的)发生在文档中任何元素上的事件时。
  • 当您的设计显式地使用事件冒泡和停止传播()来解决页面中的一些问题或特性时。

要进一步了解这一点,需要了解jQuery委托的事件处理程序是如何工作的。当你这样说的时候:

$("#myParent").on('click', 'button.actionButton', myFn);

类上安装一个通用jQuery事件处理程序。#myParent对象。当单击事件冒泡到此委托事件处理程序时,jQuery必须遍历附加到此对象的委托事件处理程序列表,并查看事件的原始元素是否与委托事件处理程序中的任何选择器匹配。

由于选择器可能相当复杂,这意味着jQuery必须解析每个选择器,然后将其与原始事件目标的特征进行比较,以确定它是否与每个选择器匹配。这不是一个廉价的行动。如果只有一个选择器,那么这没什么大不了的,但是如果将所有选择器都放在Document对象上,并且与每一个冒泡事件相比有数百个选择器,那么这可能会严重阻碍事件处理性能。

因此,您希望设置委托的事件处理程序,以便委托的事件处理程序尽可能接近目标对象。这意味着在每个委托事件处理程序中会出现更少的事件,从而提高性能。将所有委托事件放到文档对象上是最糟糕的性能,因为所有冒泡事件都必须遍历所有委托事件处理程序,并根据所有可能的委托事件选择器进行评估。这就是为什么.live()不受欢迎,因为这是.live()事实证明是非常低效的。


因此,要实现优化的性能:

  1. 只有在实际提供所需的功能或提高性能时,才使用委托事件处理。不要总是使用它,因为它很容易,因为当你真的不需要它。实际上,它在事件分派时执行的性能比直接事件绑定差。
  2. 尽可能将委托的事件处理程序附加到最近的父级到事件源。如果由于具有要捕获事件的动态元素而使用委托事件处理,则选择本身不动态的最近的父级。
  3. 对委托事件处理程序使用容易评估的选择器。如果您遵循委托事件处理的工作方式,您将了解到,必须将委托的事件处理程序与许多对象进行多次比较,因此尽可能高效地选择器或向对象添加简单的类,从而可以使用更简单的选择器,将提高委托事件处理的性能。


查看完整回答
反对 回复 2019-06-03
  • 2 回答
  • 0 关注
  • 998 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信