【发布时间】:2014-11-26 20:46:44
【问题描述】:
是否可以编写一个只选择第一个符合条件的元素并停在那里的jQuery选择器?
我知道性能不佳的:first 选择器和更好的.first() 调用,但两者似乎都选择了所有元素,然后只返回[0] 位置的元素。
假设我在一个表中有 100 行,我需要对所有这些行做些什么。它们没有 ID,而是具有唯一值的 data-guid 属性。
这是一个带有列表的示例:
<ol>
<li data-guid="guid_1">A</li>
<li data-guid="guid_2">B</li>
<li data-guid="guid_3">C</li>
<li data-guid="guid_4">D</li>
</ol>
.
var data = [
{guid: "guid_1", new_value: "I"},
{guid: "guid_2", new_value: "II"},
{guid: "guid_3", new_value: "III"},
{guid: "guid_4", new_value: "IV"}
];
var $ol = $('#list');
for (var i = 0; i < data.length; ++i) {
$('li[data-guid="' + data[i].guid + '"]', $ol).text(data[i].new_value);
}
不幸的是,这将遍历每个元素 100 次,使总 DOM 迭代达到 10,000 次。实际上,由于 GUID 是唯一的,它应该遍历第一个元素 100 次,最后一个元素只运行一次,使其运行 5,050 次。
我想我想知道是否有办法将其视为 ID 选择器,当它找到符合条件的元素然后跳出循环时它会停止。
--
squint 的解决方案(如果我的解释是正确的)
var data = [
{guid: "guid_1", new_value: "I"},
{guid: "guid_2", new_value: "II"},
{guid: "guid_3", new_value: "III"},
{guid: "guid_4", new_value: "IV"}
];
// Hashmap in case array is not the same order as list items, look up by GUID
var hashmap = {};
for (var i = 0, l = data.length; i < l; ++i) {
hashmap[data[i].guid] = data[i];
}
var $ol = $('#list');
$('li[data-guid]', $ol).text(function () {
var item = hashmap[$(this).attr('attr-guid')];
return item ? item.new_value : 'N/A';
});
【问题讨论】:
-
我想有
$(document.querySelector('CSS selector')),但我不确定它是否更高效,尽管它明确设计为只返回第一个匹配项。 -
document.getElementById("list").querySelectorAll('li[data-guid]')然后迭代结果。 -
@squint:如果您使用的是
querySelectorAll(),那么链接方法是否会更快,就像您之前的评论一样,而不是仅仅使用querySelectorAll('#list li[data-guid]')? -
可能取决于实现,但我相信通常会从右到左选择,这意味着首先会选择所有
li[data-guid],然后每个人都需要验证它是否在 @ 987654333@。如果是这样,那么它会更慢。 -
@MMiller:至于更惯用但性能更好的 jQuery 解决方案:
$("#list").find("li[data-guid]").text(function() { return data.new_value; });。如果您只需要第一个N元素,则可以将.slice(0, N)放在.text()之前。
标签: javascript jquery performance css-selectors