所有的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事件应该总是绑定到$(document)。
    你有什么理由不想这样做?
    这可以被认为是最佳做法吗? 如果不是,为什么?

    如果你已经阅读了这一切,谢谢。 我很欣赏任何/所有的反馈/见解。

    假设:

  • 使用支持.on() jQuery //至少1.7版本
  • 您希望将事件添加到动态添加的内容
  • 读数/例子:

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

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

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

    其次,您不应该在文档级绑定所有委托事件。 这正是为什么.live()被弃用的原因,因为当你有很多这样绑定的事件时,这是非常低效的。 对于委托事件处理,将它们绑定到最近的不是动态的父对象上会更有效率。

    第三,并非所有事件都可以工作,或者所有问题都可以通过授权解决。 例如,如果要截取输入控件上的键事件并阻止无效键输入到输入控件中,则无法使用委托事件处理来完成此操作,因为在事件冒泡到委托处理程序时,它已经具有已被输入控制处理,并且影响该行为为时已晚。

    以下是需要或有利事件代表团的时间:

  • 当您捕捉事件的对象被动态地创建/删除,并且您仍然希望捕获它们上的事件,而不必在每次创建新事件时都明确重新绑定事件处理程序。
  • 当你有很多对象都想要完全相同的事件处理程序(其中地段至少有数百个)。 在这种情况下,在设置时绑定一个委托事件处理程序而不是数百个或更多直接事件处理程序可能更有效。 请注意,委托事件处理在运行时总是比直接事件处理程序效率低。
  • 当您尝试捕获文档中任何元素上发生的事件时(在文档的更高级别)。
  • 当您的设计明确使用事件冒泡和stopPropagation()来解决页面中的某些问题或功能时。

  • 为了理解这一点,需要了解jQuery委派的事件处理程序是如何工作的。 当你调用这样的东西时:

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

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

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

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


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

  • 只有在实际提供您需要的功能或提高性能时才使用委派的事件处理。 不要总是使用它,因为它很容易,因为当你不需要它时。 事件调度时间实际上比直接事件绑定更糟糕。
  • 尽可能将委派的事件处理程序附加到最近的父事件处。 如果您正在使用委托事件处理,因为您有要捕获事件的动态元素,请选择不是自身动态的最接近的父元素。
  • 为委派的事件处理程序使用易于评估的选择器。 如果你遵循委托事件处理的工作方式,你会明白,委托事件处理器必须与许多对象进行很多次比较,以便尽可能高效地选择选择器或向对象添加简单的类,这样可以使用更简单的选择器提高委托事件处理的性能。

  • 事件委托是在元素实际存在于DOM之前编写处理程序的技术。 这种方法有它自己的缺点,只有在你有这样的要求时才应该使用。

    什么时候应该使用事件委派?

  • 当你为需要相同功能的更多元素绑定公共处理程序时。 (例如:表格悬停)
  • 在该示例中,如果必须使用直接绑定来绑定所有行,那么最终会为该表中的n行创建n个处理程序。 通过使用委托方法,您可以最终处理1个简单处理程序中的所有内容。
  • 当您在DOM中更频繁地添加动态内容时(例如:从表中添加/删除行)
  • 为什么你不应该使用事件授权?

  • 与将事件直接绑定到元素相比,事件委派速度较慢。
  • 它比较了它所击中的每个泡泡上的目标选择器,比较将会非常复杂。
  • 无法控制事件冒泡,直到它遇到绑定的元素。
  • PS:即使对于动态内容,如果在将内容插入到DOM后绑定处理程序,则不必使用事件委托方法。 (如果动态内容被添加不经常移除/重新添加)

    链接地址: http://www.djcxy.com/p/51455.html

    上一篇: Should all jquery events be bound to $(document)?

    下一篇: Difference between two dispose implementations?