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

时间:2012-05-09 15:44:05

标签: javascript jquery optimization jquery-plugins

初始直觉告诉我添加一个监听器,使用bind或简单的事件方法来处理jQuery元素集,例如..

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

比使用$ .each方法将侦听器逐个添加到同一个集合更合适...

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

但是当谈到插件开发时,你正在处理用户在页面生命周期内,页面加载和页面加载后很长时间内多次调用插件实例的可能性,是不是错了将处理程序应用于每个元素本身,而不是尝试将处理程序抽象为其全局类集?

我正在处理的主要问题是“在处理事件处理时调用插件的多个实例的最佳方法是什么?为了减少工作量?”我知道我们可以绑定和取消绑定,但是有更好的方法吗?

修改

插件构造的部分代码

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;

}

4 个答案:

答案 0 :(得分:4)

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

以下是jQuery源代码(它是on方法):

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

(event.js, line 936-8)

jQuery.event.add,这是执行繁重工作的方法,不需要jQuery对象;普通的DOM对象就是它所需要的。这个循环(实际上和你的一样有效)在效率方面要优越得多,因为你的代码中的大瓶颈每次都被$(this)调用。

请注意,大多数高效技术将使用具有相同on方法的事件委派。这可能如下所示:

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

使用单个jquery对象时负载较少

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

在使用初始实例时加载更多,并且还通过$(this)为每个“已缓存”元素生成新实例。如果$('.className')包含50个元素,那么现在有51个jQuery对象,而不是单个对象。

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

答案 3 :(得分:0)

唯一真正了解的方法是profile it。但是,我打赌这是一个过早优化的练习。

在循环has a negligible runtime performance hit中调用$(this)

如果在each循环中附加处理程序更简单,更清晰,请执行此操作。