将侦听器添加到 jQuery 类集的效率,与使用 $.each 相比

Efficiency of adding a listener to a jQuery class set, compared to using $.each

本文关键字:相比 each 效率 添加 侦听器 jQuery      更新时间:2023-09-26

>最初的直觉告诉我,使用绑定或简单的事件方法向jQuery元素集添加一个侦听器,例如。

$('.className').click(funcName);

比使用 $.each 方法将侦听器一个接一个地添加到同一集合中要合适得多,因为......

$('.className').each(function(){ $(this).click(funcName); });

但是,当涉及到插件开发时,并且您正在处理用户在页面的整个生命周期中多次调用插件实例的可能性,在页面加载时以及在页面加载后很长时间内通过 ajax 调用,将处理程序应用于每个元素本身而不是尝试将处理程序抽象到其全局类集是错误的吗?

我正在处理的主要问题是"在事件处理方面,处理调用插件的多个实例的最佳方法是什么?至于减少工作量?我知道我们可以绑定和解绑定,但有更好的方法吗?

编辑

来自插件结构的部分代码

init : function(){
  this.each(function(opts){
  // adding event handlers here removes
  // the need to worry about multiple instances
  // and duplicate handles over the lifetime of the page
  });
  // adding 'global' handlers here may/may not be more
  // efficient, but adds an issue of multiple instances
  return this;
}

如果你调用click一次,jQuery 将遍历整个集合并单独绑定事件。但是,它会比你的替代方案更有效地做到这一点,因为它不会为集合中的每个元素构建一个新的 jQuery 对象,这将非常慢。

以下是来自jQuery源代码的代码(它是on方法(:

return this.each( function() {
    jQuery.event.add( this, types, fn, data, selector );
});

(事件.js,第 936-8 行(

jQuery.event.add,这是

做繁重工作的方法,不需要jQuery对象;普通的DOM对象是它所需要的。这个循环(它有效地做与你的循环相同的事情(在效率方面要优越得多,因为你的代码中最大的瓶颈是$(this)每次都被调用。

请注意,最有效的技术是使用相同的on方法使用事件委派。 这可能看起来像这样:

$(document.body).on('click', '.className', funcName);

这意味着"对于document.body内的每次点击,检查它是否起源于与选择器.className匹配的元素,如果是,则运行funcName"。你可以用任何其他包含所有潜在.className元素的元素替换document.body

你的问题是关于"效率"的,我认为这意味着"客户端的速度"。可能任何合理的方法对感知性能的影响最小,因此我建议您选择最容易维护的编码模式。

$('.className').click(funcName);

负载更少,因为它使用单个 jQuery 对象

$('.className').each(function(){ $(this).click(funcName); });

当它使用初始实例时加载更多,并且还通过 $(this) 为每个"每个"元素生成一个新实例。如果$('.className')包含 50 个元素,则您现在有 51 个 jQuery 对象,而不是单个对象。

就插件开发而言,您可以使用javascript对象,并为插件的每个实例使用new。或者,您可以定义父对象类,并在其上使用.each来设置实例。我希望这有所帮助,在不知道自己在做什么的情况下很难提出建议。

唯一真正的方法是分析它。 但是,我敢打赌,这是一种过早优化的练习。

在循环中调用$(this)对运行时性能的影响可以忽略不计。

如果将处理程序附加到each循环中更容易、更干净,请执行此操作。