在jQuery中优化实时元素的选择器
Optimize live elements' selectors in jQuery
我在下面的一些链接中读到了很多关于jQuery优化的信息:
- jQuery网站,性能
- jQuery 最佳实践 - Greg Franko
- jQuery 编码标准和最佳实践
- 14 个有用的 jQuery 技巧、注释和最佳实践
以及更多...但是他们都没有提到 .on() 缓存选择器。我不知道是否有任何方法可以在这些选择器中使用缓存元素。
例如,我的script.js
文件中有很多这样的选择器。
$(document).on('click', '.menu li.remove', function(e){ ... });
$(document).on('click', '.menu li.edit', function(e){ ... });
$(document).on('click', '.menu li.action', function(e){ ... });
$(document).on('click', '.menu li.anotherAction', function(e){ ... });
等等。 .menu
是一个菜单,可以在文档中的任何位置,所以我不能使用特定的id
容器来选择它。喜欢这个:
$('#sidebar').on('click', '.menu li.action', function(e){ ... });
有没有办法优化这些选择器。检查是否存在,如果可能,则缓存.menu
。
当你需要挖掘出最后一点性能时,你可能需要抛弃抽象。
如果您自己进行委派,您肯定会看到性能改进。
因为在您给出的示例中,除了类名之外,所有委托都是相同的,所以我会绑定一个处理程序,将代码放在单独的函数中,然后手动检查e.target
及其祖先以查找.menu li
。如果找到,则检查li
的类,并调用正确的处理程序。
var handlers = {
remove: function() {/*your code*/},
edit: function() {/*your code*/},
action: function() {/*your code*/},
anotherAction: function() {/*your code*/}
};
var targets = Object.keys(handlers);
document.onclick = function(e) {
e = e || window.event;
var li;
var node = e.target || e.srcElement;
var targetClass;
do {
if (!li) {
if (node.nodeName === "LI") {
li = node;
}
} else if (node.className.indexOf("menu") > -1) {
targetClass = li.className
break;
}
} while(node = node.parentNode);
if (!targetClass)
return;
for (var i = 0; i < targets.length; i++) {
if (targetClass.indexOf(targets[i]) > -1) {
handlers[targets[i]].call(li, e);
}
}
}
在上面的代码中,当我们从e.target
向上遍历时,我们首先检查我们是否在li
上。如果是这样,请抓住它并继续一个。
随着我们的继续,我们不再需要检查li
元素,但现在我们需要检查具有 menu
类的元素。如果我们找到一个,我们获取之前找到的li
的类名,然后停止循环。
我们现在知道我们有我们的menu li.someClass
元素。因此,我们可以使用我们在li
上找到的类从我们上面创建的函数列表中查找要调用的正确函数。
您应该注意,我的.indexOf()
类测试是临时的,可能会导致误报。你应该改进它。此外,代码需要更多的调整,因为我们缓存li
而不知道它是否真的有一个我们感兴趣的类。这也应该得到解决。
如果您愿意,我会让您添加必要的调整。
我个人认为您担心速度不是问题。
如果菜单不是动态加载的,没有什么能阻止您将委托的事件处理程序与普通的 jQuery 选择器相结合,以针对更多更近的元素(例如您的 .menu
类):
例如
$('.menu').on('click', 'li.remove', function(e){ ... })
.on('click', 'li.edit', function(e){ ... })
.on('click', 'li.action', function(e){ ... })
.on('click', 'li.anotherAction', function(e){ ... });
这将在每个菜单上创建一个处理程序(以便更接近元素)。
如果您的菜单是动态加载的,那么您现有的代码就完全没问题,因为我的理解是委托的事件处理程序仅将 selector
参数应用于气泡链中的元素。如果是这种情况,无论如何,委派事件将非常快。肯定比你点击鼠标快!我从来没有遇到过委托事件处理程序的速度问题,我可能在我的插件中过度使用它们(我总是假设其中的动态内容)。
- Webdriver.io pageObject模式-通过传递参数来定义元素选择器
- 使用元素选择器向Object添加函数
- j查询未来元素选择器
- Jquery动态元素选择器
- 如何通过元素选择器获取tinyMCE编辑器实例
- 如何在 Edge Animate 中使用类元素选择器绑定 ElementAction
- jQuery在以下选择器中引用初始元素选择器
- 编写一个类似jQuery的JS元素选择器
- 并行元素选择器
- 带有元素选择器的jQuery get()函数
- Jquery Html元素选择器
- 在IE上组合了活动状态伪类和相邻元素选择器
- 仅为通过元素选择器选择的元素获取指定的属性列表
- 为什么jQuery元素[]选择器在这种情况下不起作用?
- jQuery元素选择器
- Javascript元素选择器
- 用于多个元素/选择器的字符语法
- 如何使用Jquery中的元素选择器和类选择器
- 多元素选择器上的jQuery方法链接
- 如何使用jQuery元素选择器从表单中获取输入字段的ID