是否可以编写一个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选择器,当它找到符合条件的元素然后突破循环时停止。
-
斜视解决方案(如果我的解释是正确的)
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';
});
答案 0 :(得分:1)
这只运行data.length次(参见控制台日志)
<ol id="list">
<li data-guid="1">Coffee</li>
<li data-guid="2">Tea</li>
<li data-guid="5">Milk</li>
<li data-guid="6">Water</li>
</ol>
var $ol = $('#list');
var data = [[1,"Saab"], [2,"Volvo"], [3,"BMW"], [6,"Nissan"]];
for (var i = 0; i < data.length; ++i) {
$ol.find('li[data-guid="' + data[i][0] + '"]').text(data[i][1]);
console.log(i);
}
答案 1 :(得分:0)
在jQuery中,你可以使用:first
选择器来获取集合的第一个元素,但引用官方的jQuery文档:
因为:首先是jQuery扩展而不是CSS规范的一部分,使用的查询:首先不能利用本机DOM querySelectorAll()方法提供的性能提升。要在使用时获得最佳性能:首先选择元素,首先使用纯CSS选择器选择元素,然后使用.filter(&#34;:first&#34;)。
:first
选择器和.filter()
方法都不会真正改善/提升您的代码。
如果您只想选择第一个元素,那么最好的解决方案是使用document.querySelector()
,它会在第一个元素上停止并返回它。
所以这是:
var $ol = $('#list');
for (var i = 0; i < data.length; ++i) {
$(document.querySelector('li[data-guid="' + data.guid + '"]'), $ol).text(data.new_value);
}