DOM 操作使用本地函数来执行简单的操作。浏览器供应商优化这些。您正在从 HTML 构建行。 jQuery 在内部使用 .innerHTML 构建集合,然后将其修补到浏览器的超高速解析器中。
选择比较慢,因为 JS 代码需要反复循环遍历 DOM。较新的浏览器具有本机选择处理,这为基于选择器的 JS 提供了显着的加速。随着时间的推移,这将不再是一个问题。
下面是相关查询 $(".checkbox input", row) 的分解方式:
-
row.getElementsByTagName('*');
- for 循环遍历返回的每个元素(行内的所有元素)并使用
/(\s|^)checkbox(\s|$)/ 测试 elements[i].className。
- for-loop 剩余的每个元素并收集
matched[i].getElementsByTagName('input');
- 独特的最终集合。
这与 jQuery 1.3 不同,因为它的引擎以相反的方式在选择器中移动,从获取所有输入元素开始,然后测试父元素。
请记住,JS 选择器引擎实现的 CSS 选择器规范比实际可用于 CSS(或由当前浏览器实现)的要多得多。利用这一点以及对引擎的了解,我们可以优化选择器,可以通过几种不同的方式进行优化:
如果您知道.checkbox 是什么元素类型:
$("td.checkbox input", row);
先过滤类型,然后过滤类,只过滤那些匹配项会更快。这不适用于非常小的元素子集,但在实践中几乎从未如此。
单类测试是最慢的常见selectors people actually use。
更简单的选择:
$("input[type=checkbox]", row);
一个循环比两个循环快。这只会找到输入元素,然后直接按类型属性过滤它们。由于从不使用子/子元素,因此也可能会跳过唯一性(智能引擎会尝试这样做,因为唯一性很慢)。
更直接的选择器:
$("td:first.checkbox input", row);
如果更直接 (YMMV),更复杂的选择器实际上可能会更快。
如果可能,将搜索上下文移至表格级别:
我的意思是,与其循环遍历行,并在每一行中搜索复选框,不如将它们单独放置,直到循环结束,然后一次选择它们:
$("tr td:first.checkbox input", table);
这样做的目的是消除重复启动选择器引擎的开销,而是一次完成所有事情。这是为了完整性,而不是我认为会带来巨大加速的东西。
不要选择:
从位构建行,随时分配事件。
var row = $( '<tr></tr>' );
var cell = $( '<td class="checkbox"></td>' ).appendTo( row );
$( '<input type="checkbox" name="..."/>' ).appendTo( cell ).click(/* ... */);
由于 Ajax 或您无法控制的其他模板,这可能是不可能的。此外,速度可能不值得将您的代码变成这种混乱,但有时这可能是有道理的。
或者,如果这些都不适合您,或者返回的性能提升太大,那么可能是时候重新考虑该方法了。您可以在树的上方分配一个事件侦听器并在那里获取事件,而不是每个元素的实例:
$('table').change(function(e){
// you may want a faster check...
if ( $(e.target).is('input[type=checkbox]') ) {
// do some stuff ...
}
});
这样,除非用户实际请求,否则您不会做任何事情。最快的。 :-)