【问题标题】:Looping through list items with jQuery使用 jQuery 遍历列表项
【发布时间】:2026-02-15 17:05:02
【问题描述】:

我有这段代码

listItems = $("#productList").find("li");

        for (var li in listItems) {
            var product = $(li);
            var productid = product.children(".productId").val();
            var productPrice = product.find(".productPrice").val();
            var productMSRP = product.find(".productMSRP").val();

            totalItemsHidden.val(parseInt(totalItemsHidden.val(), 10) + 1);
            subtotalHidden.val(parseFloat(subtotalHidden.val()) + parseFloat(productMSRP));
            savingsHidden.val(parseFloat(savingsHidden.val()) + parseFloat(productMSRP - productPrice));
            totalHidden.val(parseFloat(totalHidden.val()) + parseFloat(productPrice));

        }

我没有得到想要的结果——totalItems 的结果是 180+,其余的都是 NaN。我怀疑它在哪里我使用var product = $(li); 或者可能与循环本身的表达式一起使用。无论哪种方式 - 我都需要遍历标记为 #productList<ul> 中的 <li> 项目

【问题讨论】:

  • 您的“累加器”字段是否以空值开头?如果是这样,这就是您的 NaN 结果的来源。
  • 您获得 180 多个项目的原因是 for/in 包含原型属性以及实际实例的属性。可以针对 jQuery 对象调用的所有 jQuery 方法都是对象原型的一部分。如您所知,.each() 是一种常见的迭代方式,但不是唯一的方式。
  • .each 都会这样做。一个工作示例jsfiddle.net/Lijo/Hb28u/16
  • 感谢您的评论,但这是 2 年前回答的......

标签: javascript jquery


【解决方案1】:

你需要使用.each:

var listItems = $("#productList li");
listItems.each(function(idx, li) {
    var product = $(li);

    // and the rest of your code
});

这是循环 jQuery 选择的正确方法。


在现代 Javascript 中,您还可以使用 for .. of 循环:

var listItems = $("#productList li");
for (let li of listItems) {
    let product = $(li);
}

但是请注意,旧浏览器不支持这种语法,您最好使用上面的 jQuery 语法。

【讨论】:

  • 只是添加到此,您可能还想将选择器更改为 $("#productList li") 。而不是使用查找。
  • @Yads 不一定。我不确定,但原始代码很有可能在许多浏览器中会更高效,因为它不需要如此密集地解析字符串。
  • 嗯,我在 jQuery 1.4.2 中做了一些快速的基准测试。在 IE7 和 Chrome 上,使用 find 方法比聚合选择器慢大约 30%。
  • @Yads 那么公平——感谢您提供的信息。我将编辑我的答案。
【解决方案2】:

您可以为此使用each

$('#productList li').each(function(i, li) {
  var $product = $(li);  
  // your code goes here
});

话虽如此 - 您确定要每次都将值更新为 +1 吗?难道你不能只找到计数然后根据它设置值吗?

【讨论】:

  • 不需要传递 i 和 li 作为参数吗?也许我遗漏了一些东西,但我认为被操作的对象默认作为 this 对象传递给函数。
  • 不过,直言不讳从来没有什么坏处——我已经被this 咬了太多次了。 :)
  • @exoboy 你是对的,但是 jQuery 将元素和元素在所选 jQuery 列表中的索引作为参数传递。
  • @all:这就是我喜欢这个论坛的原因......很高兴看到其他观点并偶尔学习一些新东西。
【解决方案3】:

试试这个:

listItems = $("#productList").find("li").each(function(){
   var product = $(this);
   // rest of code.
});

【讨论】:

    【解决方案4】:

    试试这个代码。通过使用 parent>child 选择器“#productList li”,它应该找到所有 li 元素。然后,您可以使用 each() 方法遍历结果对象,该方法只会更改已找到的 li 元素。

    listItems = $("#productList li").each(function(){
    
            var product = $(this);
            var productid = product.children(".productId").val();
            var productPrice = product.find(".productPrice").val();
            var productMSRP = product.find(".productMSRP").val();
    
            totalItemsHidden.val(parseInt(totalItemsHidden.val(), 10) + 1);
            subtotalHidden.val(parseFloat(subtotalHidden.val()) + parseFloat(productMSRP));
            savingsHidden.val(parseFloat(savingsHidden.val()) + parseFloat(productMSRP - productPrice));
            totalHidden.val(parseFloat(totalHidden.val()) + parseFloat(productPrice));
    
        });
    

    【讨论】:

      【解决方案5】:

      要获得更明确的答案,您需要发布一些标记。您可以简化您的 jQuery,如下所示:

      $("#productList li").each(function() {
          var product = $(this);
          var productid = $(".productId", product).val();
          var productPrice = $(".productPrice", product).val();
          var productMSRP = $(".productMSRP", product).val();
      
          // the rest remains unchanged
      }
      

      【讨论】:

      • 我不会做$(".productId", $(this)),因为它只是做product.find(".productId")的一种效率较低的方式。此外,您缓存了$(this),但从未使用过它。
      • 啊,好点。我很少费心将 $(this) 分配给另一个变量,但这样做是为了保持 OP 的代码相似。
      【解决方案6】:

      要在没有 jQuery .each() 的情况下解决这个问题,你必须像这样修复你的代码:

      var listItems = $("#productList").find("li");
      var ind, len, product;
      
      for ( ind = 0, len = listItems.length; ind < len; ind++ ) {
          product = $(listItems[ind]);
      
          // ...
      }
      

      原始代码中的错误:

      1. for ... in 还将循环遍历所有继承的属性;也就是说,您还将获得由 jQuery 定义的所有函数的列表。

      2. 循环变量li 不是列表项,而是列表项的索引。在这种情况下,索引是一个普通的数组索引(即整数)

      基本上你可以使用.each(),因为它更舒服,但特别是当你循环更大的数组时,这个答案中的代码会更快。

      对于.each() 的其他替代方案,您可以查看以下性能比较: http://jsperf.com/browser-diet-jquery-each-vs-for-loop

      【讨论】:

      • 为什么不减少 for-loop 之类的(并完全删除 len 变量): for ( ind = 0; ind
      【解决方案7】:

         <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
         <script>
            $(document).ready(function() {
            $("form").submit(function(e){
                e.preventDefault();
             var name = $("#name").val();
             var amount =$("#number").val();
             var gst=(amount)*(0.18);
                 gst=Math.round(gst);
      
             var total=parseInt(amount)+parseInt(gst);
             $(".myTable tbody").append("<tr><td></td><td>"+name+"</td><td>"+amount+"</td><td>"+gst+"</td><td>"+total+"</td></tr>");
             $("#name").val('');
             $("#number").val('');
      
             $(".myTable").find("tbody").find("tr").each(function(i){
             $(this).closest('tr').find('td:first-child').text(i+1);
      
             });
      
             $("#formdata").on('submit', '.myTable', function () {
      
                         var sum = 0;
      
                $(".myTable tbody tr").each(function () {
                          var getvalue = $(this).val();
                          if ($.isNumeric(getvalue))
                           {
                              sum += parseFloat(getvalue);
                           }                  
                           });
      
                           $(".total").text(sum);
              });
      
          });
         });
      
         </script>
      
           <style>
                 #formdata{
                            float:left;
                            width:400px;
                          }
      
           </style>
        </head>
      
      
        <body>  
      
             <form id="formdata">  
      
                                 <span>Product Name</span>
                                 <input type="text" id="name">
                                  <br>
      
                                 <span>Product Amount</span>
                                 <input type="text" id="number">
                                 <br>
                                 <br>
                                 <center><button type="submit" class="adddata">Add</button></center>
             </form>
             <br>
             <br>
      
            <table class="myTable" border="1px" width="300px">
            <thead><th>s.no</th><th>Name</th><th>Amount</th><th>Gst</th><th>NetTotal</th></thead>
      
            <tbody></tbody>
      
            <tfoot>
                   <tr>
                       <td></td>
                       <td></td>
                       <td></td>
                       <td class="total"></td>
                       <td class="total"></td>
                   </tr>
      
            </tfoot>
            </table>
      
         </body>
      

      【讨论】: