【问题标题】:onClick event in a For loopFor 循环中的 onClick 事件
【发布时间】:2013-03-29 10:44:51
【问题描述】:

我尝试使用 for 创建一个循环,并通过 onclick 事件递增,但它不起作用。

js的一部分:

 var gameCase = ['', '', '', '', '', '', '', '', ''], // 9
    itemLists = $('game').getElementsByTagName('li'); // 9 items

    for( var i = 0; i < itemLists.length; i++ ) {
         // i already egal to 9
         itemLists[i].onclick = function() {
              // do something
         }
    }

但在这种情况下,在我能够单击列表元素之前,For 循环已经完成。

此外,我想获取我单击的项目列表并将其保存在数组中。我尝试了一个gameCase[this](在onclick函数中),但我不知道这是否是好方法。

【问题讨论】:

  • $('game').getElementsByTagName('li');是什么,你这里用jQuery还是纯javascript?
  • @user1479606 纯javascript,我刚刚创建了自己的选择器。

标签: javascript for-loop


【解决方案1】:

John Resig 在“JavaScript Ninja 的秘密”(http://ejohn.org/apps/learn/#59) 中很好地介绍了这个主题

您需要创建一个临时作用域来保留 i 的值

for ( var i = 0; i < itemLists.length; i++ ) (function(i){ 
  itemLists[i].onclick = function() {
      // do something
  }
})(i);

编辑:

var gameCase = ['', '', '', '', '', '', '', '', ''], // 9
$listParent = $('game').find('ul'), // li's parent
itemLists = $('game').getElementsByTagName('li'); // 9 items

var listHandler = (function() {
  var i = 0;

  return function() {
    // $(this) will in here refer to the clicked li
    i++ // increment i

    if ( i === 9 ) {
      $listParent.off('click', 'li', listHandler); //remove eventhandler when i reaches 9
    }
  }
}());

$listParent.on('click', 'li', listHandler); // attach eventhandler to ul element

这应该可以满足您的需求,因为我在工作,所以现在无法测试。

【讨论】:

  • 正如@Tim van Elsloo 所说,这是个好方法。但是有一些奇怪的事情,当我在单击列表中的任何项目之前控制台记录 i 的值时,i 值会减小。 for ( var i = 0; i &lt; itemLists.length; i++ ) (function(i){ console.log(i); //0 1 2 3 4 5 6 7 8 itemLists[i].onclick = function() { // i egal to 4 if I clicked on the third element. } })(i);
  • 长度属性从 1 开始,您的 i var 从 0 开始。因此,您要么必须将 for 循环更改为从 1 开始并以 length+1 结束,要么将函数内部更改为 itemLists[ i+1].onclick.
  • 是的,我知道,这不是问题所在。循环的兴趣在于,当 i 等于 9 时,我无能为力。但是在这里,在我单击一个元素之前,For 循环已经完成。我想,当我单击列表中的一个项目时,我增加,当我到达 9 时,循环停止。
  • 好的,所以您只想在每次单击 listItem 时增加 i ?在这种情况下,您根本不需要 for 循环。这样做是立即将 i 从 0 循环到 9 并向每个项目列表添加一个事件处理程序。当我正确理解你时,我会用我认为你需要的东西来编辑我的答案
  • 是的,这就是我想要的。
【解决方案2】:

包裹你的听众:

onclick = (function(i) {return function() {
    ...
};})(i);

这解决了您的变量范围问题。

【讨论】:

  • 这很好,当我点击一个列表项时,它会返回正确的案例编号。但是,在我开始点击之前,For 循环会增加吗?
【解决方案3】:

抱歉,如果我没有正确理解您的问题, 从我了解到的代码中,您正在尝试向游戏标签中找到的所有列表元素添加一个 onclick 处理程序(也许它应该是一个类/ID)。

当脚本标签/文件在没有任何用户交互的情况下加载时,将执行 for 循环。

如果您希望分配一个使用计数器当前值的函数。使用以下代码:

itemLists[i].onclick = (function() {
    return function() {
         // TODO ---
        // Your handler code here
}
})();

【讨论】:

    【解决方案4】:

    另一种选择是使用 forEach 循环,这会为每次迭代创建一个新变量。

    var gameCase = ['', '', '', '', '', '', '', '', ''], // 9
    itemLists = $('game').getElementsByTagName('li'); // 9 items
    
    itemLists.forEach(function(item,index){
        item.onclick = function() {
          // do something
     }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-31
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 2016-03-20
      • 2021-03-25
      相关资源
      最近更新 更多