6

最初的直觉告诉我,使用绑定或直接事件方法向一组 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;

}
4

4 回答 4

4

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

这是来自 jQuery 源的代码(它是on方法):

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

(event.js,第 936-8 行)

jQuery.event.add,这是完成繁重工作的方法,不需要 jQuery 对象;普通的 DOM 对象就是它所需要的。这个循环(实际上与您的循环相同)在效率方面要优越得多,因为$(this)每次都会调用代码中的大瓶颈。

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

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

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

于 2012-05-09T17:23:05.253 回答
1

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

于 2012-05-09T17:05:53.787 回答
1
$('.className').click(funcName);

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

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

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

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

于 2012-05-09T17:10:34.473 回答
0

唯一真正了解的方法是对其进行分析。但是,我敢打赌,这是一个过早优化的练习。

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

each如果在循环中附加处理程序更容易和更清洁,那就去做吧。

于 2012-05-09T18:19:49.523 回答