【问题标题】:Looping through two different selectors at the same time同时循环通过两个不同的选择器
【发布时间】:2011-06-07 22:11:04
【问题描述】:

我正在使用 JQuery 来计算一些总数,但遇到了问题。

假设我有两组输入,每组都有一个唯一的名称。

$('[name="quantity\\[\\]"]')
$('[name="price\\[\\]"]')

我想同时循环遍历每组输入,以便检查 (!isNaN) 和 (length !== 0),如果值有效,我想将它们相乘并添加到运行总计中。

我知道我可以使用 each() 在一个选择器中循环,但是我如何同时在两个选择器中循环呢?有没有一种优雅的方式来实现这个目标?

【问题讨论】:

  • 两组输入的数量是否相等?你能展示你正在使用的标记吗?也许是JS Fiddle demo
  • 这些字段是否成对出现在页面上?
  • @David Thomas @Šime Vidas 是的,它们成对出现,并且两个输入的数量始终相同。
  • 如果它们位于一个公共容器内,您可以遍历所有容器,并为每次迭代(容器)获取其中的两个值....

标签: javascript jquery


【解决方案1】:

除了 jQuery 所有可爱的东西,这里有一个通用的“zip”函数。

ab 应该是数组(或至少是类似数组的)。如果提供了fn,这将作为每个pair 项的map。请记住,jQuery 对象数组。

function zip (a, b, fn) {
   var len = Math.max(a.length, b.length)
   var result = []
   if (fn) {
     for (var i = 0; i < len; i++) {
       result.push(fn(a[i], b[i]))
     }
   } else {
     for (var i = 0; i < len; i++) {
       result.push([a[i], b[i]])
     }
   }
   return result
}

例子:

var z = zip([1,2,3], ['a','b'])
// z = [[1,'a'],[2,'b'],[3,undefined]
for (var i = 0; i < z.length; i++) {
    var elm = z[i]
    var a = elm[0]
    var b = elm[1]
    alert(a + "-" + b)
}

fn 为例:

zip([1,2,3], ['a','b'], function (a, b) {
    alert(a + "-" + b)
})

jQuery 上下文中的示例:

var total = 0
zip(
  $('[name="quantity\\[\\]"]'),
  $('[name="price\\[\\]"]'),
  function (a, b) {
    // if either a or b are undefined, there is already a problem
    // the `expr || 0` is to silently handle cases of `NaN || 0` which may
    // result if the price or quantity are garbage values
    var qty = parseInt($(a).val(), 10) || 0
    var price = parseInt($(b).val(), 10) || 0
    total += qty * price
  })

编码愉快。

【讨论】:

  • 不错的函数,但是你缺少很多分号:(
【解决方案2】:

这是一个简单的解决方案

var quantities = $('[name="quantity\\[\\]"]'),
    prices = $('[name="price\\[\\]"]');


var len = Math.max(quantities.size(), prices.size());
for (var i=0; i < len; i++) {
  var quantity = quantities.get(i);
  var price = prices.get(i);
  // Do whatever you want with quantity and price    
}

【讨论】:

    【解决方案3】:

    将选择结果存储在一个变量中,并在枚举时使用index 参数为each 引用另一个集合中的相关元素。

    var quan = $('[name="quantity\\[\\]"]');
    var price = $('[name="price\\[\\]"]');
    var total = 0;
    
    quan.each(function( index ) {
        var quan_val = +$(this).val();
        var price_val = +price.eq( index ).val();
    
        if( quan_val && price_val ) {
            total += (quan_val * price_val);
        }
    });
    
    alert( total );
    

    【讨论】:

      【解决方案4】:

      这个怎么样:

      function getValue() { return this.value; }
      
      var valsA = $('input[name="quantity\\[\\]"]').map(getValue).get(),
          valsB = $('input[name="price\\[\\]"]').map(getValue).get();
      
      for ( var i = 0; i < valsA.length; i++ ) {
          // work with valsA[i] and valsB[i] here
      }
      

      【讨论】:

        【解决方案5】:
        var prices = $('[name="price\\[\\]"]');
        $('[name="quantity\\[\\]"]').each(function(i){
          var quantity = this;
          var price    = prices[i];
          // Compare them here.
        });
        

        【讨论】:

          【解决方案6】:

          使用逗号:

          $('[name="quantity\\[\\]"], [name="price\\[\\]"]')
          

          【讨论】:

          • (+1) 如果还提供了元素类型,它将极大地提高选择器的性能,例如$('input[name="quantity\\[\\]"], input[name="price\\[\\]"]')
          • @Matt 我不认为 OP 想要按顺序循环遍历这些集合。我认为他想同时在两个组中循环...
          • @Šime Vidas 是对的。我不想循环通过一个,然后另一个。在每次迭代期间,我需要同时来自每种输入类型的两个值。
          【解决方案7】:

          循环并使用索引

          var quantity = $('[name="quantity\\[\\]"]')
          $('[name="price\\[\\]"]').each( function(ind){
              var currentPrice = $(this);
              var currentQuantity = quantity.eq(ind);
          });
          

          或类似的东西

          $('[name="price\\[\\]"]').each( function(ind){
              var currentPrice = $(this);
              var currentQuantity = currentPrice.closest('[name="quantity\\[\\]"]');
          });
          

          【讨论】:

            猜你喜欢
            • 2014-12-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-08-20
            • 2021-04-09
            • 1970-01-01
            相关资源
            最近更新 更多