【问题标题】:Filling array with numbers用数字填充数组
【发布时间】:2010-05-19 20:13:35
【问题描述】:

我有这样的情况: 有 8 个 div 块,其 id 类似于“rateN_wrapper”,其中“N”是 div 的数量:

<div id="rate1_wrapper">
  <a href="#" id="0_1">...</a>
  <a href="#" id="0_2">...</a>
  <a href="#" id="0_3">...</a>
</div>

<div id="rate2_wrapper">
  <a href="#" id="1_1">...</a>
  <a href="#" id="1_2">...</a>
  <a href="#" id="1_3">...</a>
</div>

...

var ratings = new Array();
for (i=0; i < 8; i++)
{
    ratings[i] = -1; // Default is unrated

}

for (i=0; i < 8; i++)
{
    $('#rate' + i + '_wrapper a').click(function() {
        ratings[i] = parseInt( $(this).attr('id').split('_')[1] );
        console.debug(ratings);
    });
}

我的工作是用单击的链接的 id(已解析)填充需要的地方的数组。但它总是只更改数组 (8) 的最新元素。为什么?

【问题讨论】:

    标签: javascript jquery arrays


    【解决方案1】:

    这是由 for 循环中的闭包引起的问题。您可以通过解析父 id 来查找 id:

    for (i=0; i < 8; i++)
    { 
      $('#rate' + i + '_wrapper a').click(function() {
        var parentId = $(this).parent('div').attr('id');
        var index = /\d/.exec(parentId);
        ratings[index] = parseInt( $(this).attr('id').split('_')[1] );
      });
    }
    

    【讨论】:

      【解决方案2】:

      因为您创建的函数正在关闭 i 变量。它会在当前值而不是创建函数时看到对 i 的引用。在 for 循环退出后,i 将是 8,因此您所有的匿名函数都将更新 ratings[8]。我认为这可能会解决它:

      for (i=0; i < 8; i++)
      {
          var idx = i;
          $('#rate' + idx + '_wrapper a').click(function() {
              ratings[idx] = parseInt( $(this).attr('id').split('_')[1] );
              console.debug(ratings);
          });
      }
      

      我不确定在循环体内声明 var 是否会在每次迭代时重新绑定它。如果是这样,那么匿名函数将只能看到 idx 在创建函数时所具有的值。这是我知道可行的方法:

      function CreateHandler(idx) {
          return function() {
              ratings[idx] = parseInt( $(this).attr('id').split('_')[1] );
              console.debug(ratings);
          }
      }
      
      for (i=0; i < 8; i++) {
          $('#rate' + idx + '_wrapper a').click(CreateHandler(i));
      }
      

      因此,您创建了一个函数,该函数将创建一个具有正确索引的匿名函数。返回的匿名函数将在创建时看到 idx 的值。

      【讨论】:

      • 使用 jquery .each() 也可以完全避免 for 循环,这可能更清楚
      • 其实想一想,如果你在匿名函数体而不是外部循环体中声明 var idx = i ,第一个例子就可以工作......
      • @jarrett 我不能在这里使用 each(),我没有对象的静态名称。
      • 你不需要一个静态名称来使用每个
      猜你喜欢
      • 2019-03-06
      • 1970-01-01
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-31
      相关资源
      最近更新 更多