是应该将所有jquery事件绑定到$(文档)? [英] Should all jquery events be bound to $(document)?

查看:103
本文介绍了是应该将所有jquery事件绑定到$(文档)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我第一次学习jQuery时,我通常附上这样的事件:

When I first learned jQuery, I normally attached events like this:

$('.my-widget a').click(function() {
    $(this).toggleClass('active');
});

在了解了有关选择器速度和事件委托的更多信息后,我在几个地方读到了jQuery事件委派将会让你的代码更快。所以我开始写这样的代码:

After learning more about selector speed and event delegation, I read in several places that "jQuery event delegation will make your code faster." So I started to write code like this:

$('.my-widget').on('click','a',function() {
    $(this).toggleClass('active');
});

这也是复制已弃用的.live()事件行为的推荐方法。这对我很重要,因为我的很多网站都在动态添加/删除小部件。上面的行为与.live()的行为完全不同,因为只有添加到现有容器.my-widget的元素才会获得行为。如果我在代码运行后动态添加另一个html块,那么这些元素将不会获取绑定到它们的事件。像这样:

This was also the recommended way to replicate the behavior of the deprecated .live() event. Which is important to me since a lot of my sites dynamically add/remove widgets all the time. The above doesn't behave exactly like .live() though, since only elements added to the already existing container '.my-widget' will get the behavior. If I dynamically add another block of html after that code has ran, those elements will not get the events bound to them. Like this:

setTimeout(function() {
    $('body').append('<div class="my-widget"><a>Click does nothing</a></div>');
}, 1000);



  1. .live()的旧行为//意味着将事件附加到尚未存在的元素

  2. .on()

  3. 绑定事件的最快性能的好处

  4. 管理事件的简单方法

  1. the old behavior of .live() // meaning attaching events to not yet existent elements
  2. the benefits of .on()
  3. fastest performance to bind events
  4. Simple way to manage events

我现在附上所有这样的事件:

I now attach all events like this:

$(document).on('click.my-widget-namespace', '.my-widget a', function() {
    $(this).toggleClass('active');
});

这似乎符合我的所有目标。 (是的,因为某种原因它在IE中速度较慢,不知道为什么?)
它很快,因为只有一个事件与单个元素相关联,而二级选择器仅在事件发生时进行评估(如果这是这里错了)。命名空间非常棒,因为它可以更容易地切换事件监听器。



Which seems to meet all my goals. (Yes it's slower in IE for some reason, no idea why?) It's fast because only a single event is tied to a singular element and the secondary selector is only evaluated when the event occurs (please correct me if this is wrong here). The namespace is awesome since it makes it easier to toggle the event listener.

所以我我开始认为jQuery事件应该总是绑定到$(文档)。

你有什么理由不想这样做吗?

这可能吗被认为是最佳做法?如果没有,为什么?

So I'm starting to think that jQuery events should always be bound to $(document).
Is there any reason why you would not want to do this?
Could this be considered a best practice? If not, why?

如果您已经读完了这一切,谢谢。我感谢任何/所有反馈/见解。

If you've read this whole thing, thank you. I appreciate any/all feedback/insights.

假设:


  1. 使用支持的jQuery。 on() //至少版本1.7

  2. 您希望将事件添加到动态添加的内容

  1. Using jQuery that supports .on() // at least version 1.7
  2. You want the the event to be added to dynamically added content

读物/示例:


  1. http://24ways.org/2011/your-jquery-now-with-less-suck

  2. http://brandonaaron.net/ blog / 2010/03/4 / event-delegation-with-jquery

  3. http://www.jasonbuckboyer.com/playground/speed/speed.html

  4. http://api.jquery.com/on/

  1. http://24ways.org/2011/your-jquery-now-with-less-suck
  2. http://brandonaaron.net/blog/2010/03/4/event-delegation-with-jquery
  3. http://www.jasonbuckboyer.com/playground/speed/speed.html
  4. http://api.jquery.com/on/


推荐答案

否 - 您不应将所有委派的事件处理程序绑定到 docu对象对象。这可能是您可以创建的性能最差的场景。

No - you should NOT bind all delegated event handlers to the document object. That is probably the worst performing scenario you could create.

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

First off, event delegation does not always make your code faster. In some cases, it's is advantageous and in some cases not. You should use event delegation when you actually need event delegation and when you benefit from it. Otherwise, you should bind event handlers directly to the objects where the event happens as this will generally be more efficient.

其次,您不应该在文档级别绑定所有委派的事件。这正是为什么 .live()被弃用的原因,因为当你以这种方式绑定大量事件时,效率非常低。对于委托事件处理,将它们绑定到非动态的最近父节点会更有效率。

Second off, you should NOT bind all delegated events at the document level. This is exactly why .live() was deprecated because this is very inefficient when you have lots of events bound this way. For delegated event handling it is MUCH more efficient to bind them to the closest parent that is not dynamic.

第三,关闭,并非所有事件都有效或所有问题都可以通过代表团。例如,如果要拦截输入控件上的键事件并阻止将无效键输入到输入控件中,则无法通过委派事件处理来执行此操作,因为当事件冒泡到委派处理程序时,它已经已由输入控件处理,影响该行为为时已晚。

Third off, not all events work or all problems can be solved with delegation. For example, if you want to intercept key events on an input control and block invalid keys from being entered into the input control, you cannot do that with delegated event handling because by the time the event bubbles up to the delegated handler, it has already been processed by the input control and it's too late to influence that behavior.

以下是需要或有利的事件委托时间:

Here are times when event delegation is required or advantageous:


  • 当您捕获事件的对象被动态创建/删除时,您仍然希望捕获它们上的事件,而不必在每次创建新事件时都显式重新绑定事件处理程序。

  • 当你有很多对象都需要完全相同的事件处理程序(其中批量至少为数百个)。在这种情况下,在设置时绑定一个委托事件处理程序而不是数百个或更多直接事件处理程序可能更有效。请注意,委派事件处理在运行时的效率始终低于直接事件处理程序。

  • 当您尝试捕获(在文档中的更高级别)任何事件发生时文档中的元素。

  • 当您的设计明确使用事件冒泡和stopPropagation()来解决页面中的某些问题或功能时。

  • When the objects you are capturing events on are dynamically created/removed and you still want to capture events on them without having to explicitly rebind event handlers every time you create a new one.
  • When you have lots of objects that all want the exact same event handler (where lots is at least hundreds). In this case, it may be more efficient at setup time to bind one delegated event handler rather than hundreds or more direct event handlers. Note, delegated event handling is always less efficient at run-time than direct event handlers.
  • When you're trying to capture (at a higher level in your document) events that occur on any element in the document.
  • When your design is explicitly using event bubbling and stopPropagation() to solve some problem or feature in your page.

要了解这一点,需要了解jQuery委派事件处理程序的工作原理。当您拨打以下内容时:

To understand this a little more, one needs to understand how jQuery delegated event handlers work. When you call something like this:

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

它在 #myParent 对象。当click事件冒泡到此委托事件处理程序时,jQuery必须遍历附加到此对象的委托事件处理程序列表,并查看该事件的原始元素是否与委派事件处理程序中的任何选择器匹配。

It installs a generic jQuery event handler on the #myParent object. When a click event bubbles up to this delegated event handler, jQuery has to go through the list of delegated event handlers attached to this object and see if the originating element for the event matches any of the selectors in the delegated event handlers.

因为选择器可以公平地参与,这意味着jQuery必须解析每个选择器,然后将其与原始事件目标的特征进行比较,以查看它是否与每个选择器匹配。这不是一个便宜的操作。如果只有其中一个,这没什么大不了的,但是如果你把所有选择器放在文档对象上并且有数百个选择器可以与每个冒泡事件进行比较,那么这可能会严重影响事件处理性能。

Because selectors can be fairly involved, this means that jQuery has to parse each selector and then compare it to the characteristics of the original event target to see if it matches each selector. This is not a cheap operation. It's no big deal if there is only one of them, but if you put all your selectors on the document object and there were hundreds of selectors to compare to every single bubbled event, this can seriously start to hobble event handling performance.

因此,您需要设置委派的事件处理程序,以便委托事件处理程序尽可能接近目标对象。这意味着每个委托事件处理程序中的事件将会减少,从而提高性能。将所有委派事件放在文档对象上是最糟糕的性能,因为所有冒泡事件都必须通过所有委托事件处理程序并针对所有可能的委托事件选择器进行评估。这正是为什么 .live()被弃用的原因,因为这就是 .live()所做的事情,它证明了非常低效。

For this reason, you want to set up your delegated event handlers so a delegated event handler is as close to the target object as practical. This means that fewer events will bubble through each delegated event handler, thus improving the performance. Putting all delegated events on the document object is the worst possible performance because all bubbled events have to go through all delegated event handlers and get evaluated against all possible delegated event selectors. This is exactly why .live() is deprecated because this is what .live() did and it proved to be very inefficient.

因此,要实现最佳性能:

So, to achieve optimized performance:


  1. 仅在实际提供所需功能或提高性能时才使用委派事件处理。不要总是使用它,因为它很容易,因为当你实际上不需要它时。它实际上在事件发送时比直接事件绑定表现更差。

  2. 将委派的事件处理程序尽可能地附加到事件源的最近父级。如果您正在使用委托事件处理,因为您有要为其捕获事件的动态元素,则选择最接近其本身不动态的父级。

  3. 使用易于评估的选择器委派的事件处理程序。如果您遵循委托事件处理的工作原理,您将理解委托事件处理程序必须多次与大量对象进行比较,以便尽可能高效地选择选择器或向对象添加简单类,以便可以使用更简单的选择器提高委派事件处理的性能。

这篇关于是应该将所有jquery事件绑定到$(文档)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆