如何在Javascript中使用循环生成事件处理程序?

Cab*_*ero 21 javascript

例如,我有一个从AJAX响应生成的10个标签:

<a href="#" id="b1">b1</a>
<a href="#" id="b2">b2</a>
<a href="#" id="b3">b3</a>
<a href="#" id="b4">b4</a>
<a href="#" id="b5">b5</a>
<a href="#" id="b6">b6</a>
<a href="#" id="b7">b7</a>
<a href="#" id="b8">b8</a>
<a href="#" id="b9">b9</a>
<a href="#" id="b10">b10</a>
Run Code Online (Sandbox Code Playgroud)

我需要通过循环为每个人分配onclick事件:

for(i=1; i<11; i++) {
    document.getElementById("b"+i).onclick=function() {
        alert(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,它只分配onclick到最后一个标签并提醒"11".我怎样才能让它发挥作用?我宁愿不使用jQuery.

SLa*_*aks 36

所有处理程序都共享相同的i变量.

您需要将每个处理程序放入一个单独的函数中,该函数将i参数作为参数,以便每个函数都获得自己的变量:

function handleElement(i) {
    document.getElementById("b"+i).onclick=function() {
        alert(i);
    };
}

for(i=1; i<11; i++) 
    handleElement(i);
Run Code Online (Sandbox Code Playgroud)


Kev*_*vin 19

关闭是你正在寻找的:

for(i=1; i<11; i++) {
    (function(i) {
        document.getElementById("b"+i).onclick=function() {
            alert(i);
        };
    })(i);
}
Run Code Online (Sandbox Code Playgroud)

  • 我会说卡瓦列罗有一个关闭,他们不想要一个关闭,他们想要一个关闭破坏者强迫立即评估`i`.这就是你的自动执行功能正在做的事情. (2认同)

Mar*_*sev 6

有两种方法可以在这个问题上使用闭包.我们的想法是为事件处理程序使用的每次迭代创建一个带有"i"变量快照的作用域.

解决方案#1(凯文提到):

for(i=1; i<11; i++) {
    (function(num) {

       document.getElementById("b"+num).addEventListener('click', function() {
            alert(num);
       });

    })(i);
}
Run Code Online (Sandbox Code Playgroud)

解决方案#2:

for (i=1; i<11; i++) {
    document.getElementById("b"+i).addEventListener('click', (function(){
        var num = i;
        return function() {
            alert(num);
        }
    })());
}
Run Code Online (Sandbox Code Playgroud)