【问题标题】:Why the listener is displaying always the number of the last iteration?为什么监听器总是显示最后一次迭代的次数?
【发布时间】:2018-11-29 18:25:21
【问题描述】:

无论您点击什么数字,警报都会显示数字 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>

【问题讨论】:

    标签: javascript html loops templates addeventlistener


    【解决方案1】:

    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()

    【讨论】:

    • 我以为 addEventListener 已经被立即执行了。谢谢你的解释!
    【解决方案2】:

    这是一个经典的closure 错误。

    替换

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

    通过

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

    【讨论】:

    • 与 Yosvel 解决方案一样有效。
    • 但我担心移动浏览器不支持此解决方案。 caniuse.com/#search=let
    • 例子中涉及到闭包,但不是闭包错误。这是一个范围错误。你需要创建一个新的范围 => 如果 ES6/ES2015 是一个选项,使用 let 是一个很好的解决方案。使用 IIFE 将适用于 ES5 和旧版浏览器。
    猜你喜欢
    • 2014-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-09
    • 2017-12-10
    • 2015-08-31
    • 1970-01-01
    相关资源
    最近更新 更多