为什么侦听器总是显示上一次迭代的编号?

时间:2018-06-20 15:00:24

标签: javascript html loops templates addeventlistener

无论您单击什么数字,警报都会显示数字10。 也许这不是在循环中使用addEventListener的最佳方法。 需要一些帮助。谢谢。

<table id="tb1"></table>

<template id="tp1">
    <tr>
        <td class="num"></td>
    </tr>
</template>

<script>

    var t = document.getElementById("tp1");
    var tb1 = document.getElementById("tb1");

    for (i=0;i<10;i++){

        var clone = t.content.cloneNode(true);

        clone.querySelector(".num").innerHTML = i;

        var l = clone.querySelector("tr");
        l.id = i;

        clone.getElementById(i).addEventListener("click",function(){
            alert(i);            
        });

        tb1.append(clone);
    }

</script>

2 个答案:

答案 0 :(得分:4)

i变量通过引用获取循环的最后一个值。在这种情况下,为10

如果函数变为立即执行的函数表达式,则可以使用IIFE解决此问题。表达式中的变量不能从外部访问

代码示例:

var t = document.getElementById('tp1');
var tb1 = document.getElementById('tb1');

for (var i = 0; i < 10; i++) {
  var clone = t.content.cloneNode(true);
  clone.querySelector('.num').innerHTML = i;
  var l = clone.querySelector('tr');
  l.id = i;
  (function (i) {
    clone.getElementById(i).addEventListener('click', function () {
      console.log(i);
    });
  })(i);
  tb1.append(clone);
}
<table id="tb1"></table>

<template id="tp1">
    <tr>
        <td class="num"></td>
    </tr>
</template>

注意:为了方便起见,我已将alert()的使用替换为console.log()

答案 1 :(得分:3)

这是经典的closure错误。

替换

for (i=0;i<10;i++)

作者

for (let i=0;i<10;i++)