jQuery - 仅选择匹配性能的第一个元素

时间:2014-10-01 21:34:27

标签: javascript jquery performance css-selectors

是否可以编写一个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';
});

2 个答案:

答案 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);
    }

http://jsfiddle.net/rLbd7fuc/

答案 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);
}