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

Javascript 与使用$.each相比,将侦听器添加到jQuery类集中的效率,javascript,jquery,optimization,jquery-plugins,Javascript,Jquery,Optimization,Jquery Plugins,最初的直觉告诉我,使用bind或直接事件方法向jQuery元素集添加侦听器,例如 $('.className')。单击(funcName) 比使用$更合适。每个方法将一个侦听器逐个添加到同一集中,如 $('.className')。每个(function(){$(this)。单击(functname);}) 但是,当涉及到插件开发时,如果用户在页面的整个生命周期内多次调用插件实例,在页面加载时以及在页面加载后很长时间内通过ajax调用插件实例,那么将处理程序应用于每个元素本身是否错误,而不是试图

最初的直觉告诉我,使用bind或直接事件方法向jQuery元素集添加侦听器,例如

$('.className')。单击(funcName)

比使用$更合适。每个方法将一个侦听器逐个添加到同一集中,如

$('.className')。每个(function(){$(this)。单击(functname);})

但是,当涉及到插件开发时,如果用户在页面的整个生命周期内多次调用插件实例,在页面加载时以及在页面加载后很长时间内通过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;

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

$('.className').click(funcName);
由于使用单个jquery对象,因此负载更少

$('.className').each(function(){ $(this).click(funcName); });
当它使用初始实例时会有更多的负载,并且还会通过
$(this)
为每个“eached”元素生成一个新实例。如果
$('.className')
包含50个元素,那么现在就有51个jQuery对象,而不是一个对象


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

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

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

jQuery.event.add
,这是一种执行繁重任务的方法,不需要jQuery对象;普通DOM对象就是它所需要的。这个循环(有效地完成了与您相同的事情)在效率方面要高得多,因为代码中的最大瓶颈是每次调用
$(This)

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

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

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

唯一真正知道的方法是。然而,我敢打赌这是一个过早优化的练习

在循环中调用
$(this)


如果在
每个
循环中附加处理程序更容易、更干净,那么就这样做。

$('.className')。单击
可能会在某个阶段在内部使用
。each()
。我想知道这实际上……请参见:(
。单击
调用
)。这一切归结为
addEventListener
attachEvents
在某个阶段是1-1绑定b/w元素和处理程序,因此
$('.className')
将在某个点进行内部迭代以绑定相应的处理程序。您能提供一个这样的示例吗?谢谢您的回答,这绝对是关于内部运行方式的好信息。然而,我更关心的是插件的范围。用于插件开发的通用“init”方法将使用$.each来循环集合,因此我已经必须循环元素集合。问题在于是在循环中绑定事件,还是在循环之后全局绑定事件。我将编辑我的问题以解释………为集合中的每个元素构建一个新的jQuery对象,这将非常缓慢。”--在
中执行
$(这)
对每个
的性能影响非常小,不值得担心。@josh3736它取决于应用程序的大小。过度使用jQuery对象是当前javascript开发中的一个大问题。这可能只是一个小的性能影响,但它加起来是值得避免的。@Freshyeball,在我链接到的问题中,你会看到,即使对
$(this)
进行了大量不切实际的调用(每秒数千次),性能影响也只有7%。(如果要附加数千个事件处理程序,则存在更大的问题。)这里的要点是,这可能是过早的优化;不要为了微小的运行时收益而增加复杂性,从而使开发和维护成为噩梦。
$(document.body).on('click', '.className', funcName);