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