如何使用函数动态定义javascript事件处理程序

时间:2012-04-02 20:06:30

标签: javascript function scope

我对Javascript有点新鲜,我似乎无法弄清楚我的功能究竟发生了什么。

背景:我的脚本应该允许你为一个元素分配一个“toggler”或“toggled”的类,让它们自动链接,所以检查/取消选中切换器将显示/隐藏切换(我知道有许多库可以做到这一点,但遗憾的是我不能在这种情况下使用它们)

脚本在pageload上执行,并在元素中搜索具有类“toggler”的元素,然后相应地分配其onclick处理程序。以下是我遇到问题的代码:

  function makeToggle () {
    for (i=0;i<toggler.length;i++) { 
      toggler[i].onclick=function(){toggleSection(this,i)};
    }
  }

  function toggleSection(obj,index) {
    if (obj.checked==true) {
      toggled[index].style.display="inline-block";
    } else {
      toggled[index].style.display="none";
    }
  }

“This”正确传递并解析为它应用的任何复选框,但“index”始终设置为toggler数组的长度而不是递增。例如,第一个和第二个切换者的onclick应为:

onclick="toggleSection(this,0)"
onclick="toggleSection(this,1)"

它们实际设置的内容(假设我有5个元素被定义为转换器)是:

onclick="toggleSection(this,5)"
onclick="toggleSection(this,5)"

从我读过的内容来看,我认为这是一个范围问题,或者我称之为函数的方式,但我发现的任何内容都没有多大意义

2 个答案:

答案 0 :(得分:1)

在创建函数时,不能像这样使用变量 i 。如果您这样做, i 的值将是 i 的最后一个值。在您的问题中将始终是切换者的长度。

所以你应该将变量( i )作为参数传递给你的onclick函数,

尝试这样,

function makeToggle () {
    for (i=0;i<toggler.length;i++) { 
      toggler[i].addEventListener("click", (function(d) { return function(){ 
                    toggleSection(this,d);
      }; })(i), true);
    }
}

或以你的风格,

function makeToggle () {
    for (i=0;i<toggler.length;i++) { 
       toggler[i].onclick = (function(d) { return function(){toggleSection(this,d)}})(i);
    }
}

答案 1 :(得分:0)

您在this blog post详细了解问题。

  

原因很复杂。我们定义为事件处理程序的匿名函数从attachEventsToListItems的范围继承“变量i”,而不是for循环。但是,到执行事件处理程序时,for循环已完成其迭代,并且此函数中的i值已变为4.此处的问题是我们定义为事件处理程序的函数不会创建新范围为了我,直到它们被执行。

要解决此问题,您需要一个闭包:

for (i=0;i<toggler.length;i++) { 
    toggler[i].onclick= (function (index) {
        return function() {
            toggleSection(this,index);
        };
    }) (i);
}

你可以在演员身上看到它:http://jsfiddle.net/Vb2t2/