【发布时间】:2011-06-03 18:17:25
【问题描述】:
我正在为 jQuery 编写一个扩展,使用
向 DOM 元素添加数据el.data('lalala', my_data);
然后使用该数据动态上传元素。
每次我从服务器获取新数据时,我都需要更新所有具有的元素
el.data('lalala') != null;
为了获得所有需要的元素,我使用James Padolsey 的扩展:
$(':data(lalala)').each(...);
一切都很好,直到我遇到需要运行该代码 50 次的情况 - 它非常慢!使用 3640 个 DOM 元素在我的页面上执行大约需要 8 秒
var x, t = (new Date).getTime();
for (n=0; n < 50; n++) {
jQuery(':data(lalala)').each(function() {
x++;
});
};
console.log(((new Date).getTime()-t)/1000);
由于我不需要 RegExp 作为 :data 选择器的参数,因此我尝试将其替换为
var x, t = (new Date).getTime();
for (n=0; n < 50; n++) {
jQuery('*').each(function() {
if ($(this).data('lalala'))
x++;
});
};
console.log(((new Date).getTime()-t)/1000);
这段代码更快(5 秒),但我想要更多。
问有没有更快的方法来使用这个数据键获取所有元素?
事实上,我可以保留一个包含我需要的所有元素的数组,因为我在我的模块中执行.data('key')。检查 100 个具有所需 .data('lalala') 的元素比检查 3640 更好:)
所以解决方案是这样的
for (i in elements) {
el = elements[i];
....
但有时元素会从页面中删除(使用 jQuery .remove())。上述两种解决方案 [$(':data(lalala)') 解决方案和if ($(this).data('lalala'))] 将跳过已删除的项目(如我所愿),而带有数组的解决方案仍将指向已删除的元素(实际上,该元素不会被真正删除 - 它只会从 DOM 树中删除 - 因为我的数组仍然有引用)。
我发现.remove()也会从节点中删除数据,所以我的解决方案会变成
var toRemove = [];
for (vari in elements) {
var el = elements[i];
if ($(el).data('lalala'))
....
else
toRemove.push(i);
};
for (var ii in toRemove)
elements.splice(toRemove[ii], 1); // remove element from array
这个解决方案快了 100 倍!
Q当从该数组中删除 DOM 元素时,垃圾收集器会释放内存吗?
请记住,DOM 树已经引用了元素,我们在数组中创建了一个新引用,然后用.remove() 删除,然后从数组中删除。
有没有更好的方法来做到这一点?
【问题讨论】:
-
您已经在此提出了 2-3 个问题。您真正想要回答的问题是哪个?
-
两个Q。第一个更有趣。
标签: javascript jquery performance jquery-selectors