使用 javascript 的项列表的循环

Loop of a list of items with javascript

本文关键字:循环 列表 使用 javascript      更新时间:2023-09-26

我读到为了提高jquery的性能应该避免使用,因为有些东西有点慢了。其中包括each()的方法,并且使用 for 循环是合适的......(根据我读到的网络文章,该方法each()大约是循环JavaScript的10倍(。

我正在尝试使用 js,但我有一些问题:/

Jquery

$('#block-system-main-menu li').each(function () {      
        var text= ($(this).children('a').text());
        if (text == 'Map' || text== 'Vul' || text== 'Equa'){
            $(this).children('a').append('<span style="float:right; margin-right: 15%; line-height: inherit;" class="fa fa-chevron-right"></span>');
        }                   
    }); 

爪哇语

var voce= $('#block-system-main-menu li');
for(var i=0; i< voce.length; i++) {
        var text= (voce[i].children('a').text());           
        if (text == 'Map' || text== 'Vul' || text== 'Equa'){
            voce[i].children('a').append('<span style="float:right; margin-right: 15%; line-height: inherit;" class="fa fa-chevron-right"></span>');
        } 
    }

但是循环不起作用,我不明白为什么....

谢谢!

你的问题就在这里。比较:

var text= ($(this).children('a').text());

跟:

var text= (voce[i].children('a').text());

在第一种情况下,您将使用 $(this) 创建 jquery 对象。在第二种情况下,你不是。 voce[i]给你一个HTML元素,它没有一个名为children的函数。所以你应该在那里得到一个错误。要使其工作,您需要从 voce[i] 创建一个 jquery 对象。像这样:

var text = $(voce[i]).children('a').text();

或者正如@GuerasArnaud在他的回答中所建议的那样:

var text= voce.eq(i).children('a').text(); 

但是,foreach很可能不是减慢代码速度的原因。您实际上应该分析代码并确定代码中的瓶颈。

虽然当你读到">x比y慢"时,你当然应该记住这一点,但你也应该尝试了解它在哪里适用并且真正重要。我不会在所有情况下都完全避免each,因为有时代码的便利性和可读性比在非关键代码部分中对代码性能进行微优化更为重要。

另请注意,在链接的教程中,您已经锁定了foreach的点,而错过了Cache. ALWAYS. 因此,在您的 jquery 代码中,您将创建两次 $(this) 对象(尽管在这种情况下它并不那么重要,因为您没有使用选择器,这取决于您的 if 子句计算结果的频率true, 但这仍然是一种成本,不会给你带来任何回报(。

所以如果你有这个,你的循环会更好:

$('#block-system-main-menu li').each(function () {  
    var children = $(this).children('a');
    var text = children.text();
    if (text == 'Map' || text== 'Vul' || text== 'Equa'){
        children.append('<span style="float:right; margin-right: 15%; line-height: inherit;" class="fa fa-chevron-right"></span>');
    }                   
}); 

或者对于for循环:

var voce= $('#block-system-main-menu li');
for(var i=0; i< voce.length; i++) {
    var children = $(voce[i]).children('a');
    var text = children.text();           
    if (text == 'Map' || text== 'Vul' || text== 'Equa'){
        children.append('<span style="float:right; margin-right: 15%; line-height: inherit;" class="fa fa-chevron-right"></span>');
    } 
}

但同样,除非voce.length非常大,否则我怀疑你是否会发现现实世界的性能有任何显着差异。

voce是一个jQuery对象,但voce[i]是一个HTMLNode Element,它没有.children()方法。如果你想留在"jquery喜欢",你应该使用.eq()

var text= voce.eq(i).children('a').text();          
所以我使用 jQuery

方法将 jQuery each与固定的 JS for 循环进行了基准测试,并添加了一个普通的 JS 解决方案: http://jsperf.com/jquery-each-for-loop

在我的机器上,jQuery.each vs JS for彼此非常接近,原版 JS 的性能都比两者高出相当大的优势。

没有jQuery的代码:

var voce = [].slice.call( document.querySelectorAll('#block-system-main-menu li'));
/* prepare the span to use .appendChild instead of innerHTML += */
var span = document.createElement('span');
    span.style.cssText = 'float:right; margin-right: 15%; line-height: inherit';
    span.className = 'fa fa-chevron-right';
for(var i=0;i<voce.length;i++){
   /* get the textContent with innerText fallback */
   var text = voce[i].textContent || voce[i].innerText;
   if (text == 'Map' || text == 'Vul' || text == 'Equa') {
       /* forEach to keep compatibility with .children('a') method which returns a collection. 
          Could be optimized further if you know you need to modify a single element */
       [].forEach.call( voce[i].querySelectorAll('a'), function(a){
           a.appendChild( span.cloneNode() );
       })
   }
}