简体   繁体   English

addEventListener的循环对于function()不是动态的

[英]Loop with addEventListener is not dynamic for function()

I want to make an extremely easy for loop to call a function with a different parameter for each button. 我想让for循环极其容易地为每个按钮调用具有不同参数的函数。 However, when I run the call and click the button, the eventListener function saveList(listIdx) only returns the function saveList("5"). 但是,当我运行调用并单击按钮时,eventListener函数saveList(listIdx)仅返回函数saveList(“ 5”)。 PLease take a look at my problem and trouble shooting. 请看看我的问题和解决方法。

    for (var listIdx = 0; listIdx < count; listIdx++ ) {
            console.log("setting the variable" + "myButton" + listIdx );

            document.getElementById("myButton" + listIdx).addEventListener("click", function() { saveList(listIdx); 
            });
    }

Attempt 1: Add a parameter to the function() call 尝试1:将参数添加到function()调用

    for (var listIdx = 0; listIdx < count; listIdx++ ) {
            console.log("setting the variable" + "myButton" + listIdx );

            document.getElementById("myButton" + listIdx).addEventListener("click", function(listIdx) { saveList(listIdx); 
            });
    }

Attempt 2: wrapper on the element 尝试2:元素上的包装器

    for (var listIdx = 0; listIdx < count; listIdx++ ) {
            console.log("setting the variable" + "myButton" + listIdx );

            document.getElementById("myButton" + listIdx).addEventListener("click", function(_listIdx) { saveList(_listIdx); 
            });
    }

The problem is that function is being called at a later point in time – after for loop is finished. 问题是在for循环完成后,该函数将在以后的某个时间点被调用。 The variable contained in the body has already been updated in the last iteration of for loop. 主体中包含的变量已经在for循环的最后一次迭代中进行了更新。 That's what you are seeing. 那就是你所看到的。

The fix is to somehow push the variable to the function inside. 解决办法是将变量以某种方式推送到函数内部。

function makeListSaver(index) {
    /* return a brand new function that has captured the index when this function 
       was invoked
    */
    return function() { 
        saveList(index);
    }
}

and then do, 然后做

document.getElementById("myButton" + listIdx).addEventListener("click", makeListSaver(listIdx))

Or simply, 或者简单地说,

document.getElementById("myButton" + listIdx).addEventListener("click", (function(index){
   return function() { saveList(index); }
})(listIdx));

You'll have to read up a little bit on closures and how they work. 您必须阅读一些有关闭包及其工作原理的信息。

Problem is the loop. 问题是循环。

Here a quick example of how to set addEventListener in a for loop. 这是一个如何在for循环中设置addEventListener的快速示例。

http://jsbin.com/kavowucimi/1/ http://jsbin.com/kavowucimi/1/

How does it works: 运作方式:

  • When page load 页面加载时
  • Find all elements with class obj. 查找所有带有obj类的元素。
  • For each element add an event listener click. 为每个元素添加一个事件侦听器。
  • When user click, alerts id for selected element. 用户单击时,警报选定元素的ID。

<script>
    window.app = {
        start: function(){
            var elms = document.querySelectorAll('.obj');

            for (var i = 0; i < elms.length; i++ ) {
                var t = elms[i];
                var elm = document.getElementById(t.id);
                elm.addEventListener('click', function(item){
                    alert(item.currentTarget.id);
                });
            }
        }
    };

    </script>

<body onload="window.app.start();">
<div id=1 class="obj">1</div>
<div id=2 class="obj">2</div>
<div id=3 class="obj">3</div>

You can do it this way... 你可以这样

for (var listIdx = 0; listIdx < count; listIdx++ ) {
           applyEvent(listIdx);
    }

function applyEvent(listIdx)
{   
        document.getElementById("1" + listIdx).addEventListener("click", function({                
              saveList(listIdx); 
        });
}

Working Fiddle 工作小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM