初始直觉告诉我添加一个监听器,使用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;
}
答案 0 :(得分:4)
如果你调用click
一次,jQuery将遍历整个集合并单独绑定事件。 然而,它会比你的替代方案更有效率,因为它不会为集合中的每个元素构建一个新的jQuery对象,这将非常慢。
以下是jQuery源代码(它是on
方法):
return this.each( function() {
jQuery.event.add( this, types, fn, data, selector );
});
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
循环中附加处理程序更简单,更清晰,请执行此操作。