否-您不应将所有委托的事件处理程序绑定到document
对象。这可能是您所能创建的最糟糕的执行场景。
首先,事件委托并不总是使代码更快。在某些情况下,它是有利的,在某些情况下不是。当您实际需要事件委托并从中受益时,您应该使用事件委托。否则,您应该将事件处理程序直接绑定到事件发生的对象,因为这通常会更有效。
其次,不应在文档级别绑定所有委托事件。这就是为什么.live()
被否决,因为这是非常低效的,当你有很多事件这样绑定。对于委托事件处理,将它们绑定到非动态的最接近的父级更有效。
第三,并不是所有的事件都可以通过委托解决所有的问题。例如,如果您想拦截输入控件上的键事件并阻止无效键被输入到输入控件中,则不能使用委托的事件处理来执行此操作,因为当事件冒泡到委托处理程序时,输入控件已经对其进行了处理,而且影响该行为为时已晚。
在这里,事件委托是必需的或有利的:
- 当您捕获事件的对象被动态创建/删除时,您仍然希望捕获事件,而不必每次创建新事件时都显式地重新绑定事件处理程序。
- 当您有很多对象都需要完全相同的事件处理程序时(其中很多对象至少是数百个)。在这种情况下,在安装时绑定一个委托事件处理程序可能比绑定数百个或更多直接事件处理程序更有效。注意,与直接事件处理程序相比,在运行时委托事件处理总是效率较低.
- 当您试图捕获(文档中较高级别的)发生在文档中任何元素上的事件时。
- 当您的设计显式地使用事件冒泡和停止传播()来解决页面中的一些问题或特性时。
要进一步了解这一点,需要了解jQuery委托的事件处理程序是如何工作的。当你这样说的时候:
$("#myParent").on('click', 'button.actionButton', myFn);
类上安装一个通用jQuery事件处理程序。#myParent
对象。当单击事件冒泡到此委托事件处理程序时,jQuery必须遍历附加到此对象的委托事件处理程序列表,并查看事件的原始元素是否与委托事件处理程序中的任何选择器匹配。
由于选择器可能相当复杂,这意味着jQuery必须解析每个选择器,然后将其与原始事件目标的特征进行比较,以确定它是否与每个选择器匹配。这不是一个廉价的行动。如果只有一个选择器,那么这没什么大不了的,但是如果将所有选择器都放在Document对象上,并且与每一个冒泡事件相比有数百个选择器,那么这可能会严重阻碍事件处理性能。
因此,您希望设置委托的事件处理程序,以便委托的事件处理程序尽可能接近目标对象。这意味着在每个委托事件处理程序中会出现更少的事件,从而提高性能。将所有委托事件放到文档对象上是最糟糕的性能,因为所有冒泡事件都必须遍历所有委托事件处理程序,并根据所有可能的委托事件选择器进行评估。这就是为什么.live()
不受欢迎,因为这是.live()
事实证明是非常低效的。
因此,要实现优化的性能:
- 只有在实际提供所需的功能或提高性能时,才使用委托事件处理。不要总是使用它,因为它很容易,因为当你真的不需要它。实际上,它在事件分派时执行的性能比直接事件绑定差。
- 尽可能将委托的事件处理程序附加到最近的父级到事件源。如果由于具有要捕获事件的动态元素而使用委托事件处理,则选择本身不动态的最近的父级。
- 对委托事件处理程序使用容易评估的选择器。如果您遵循委托事件处理的工作方式,您将了解到,必须将委托的事件处理程序与许多对象进行多次比较,因此尽可能高效地选择器或向对象添加简单的类,从而可以使用更简单的选择器,将提高委托事件处理的性能。