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

How to define javascript event handlers dynamically with a function

本文关键字:javascript 事件处理 程序 定义 动态 何使用 函数      更新时间:2023-09-26

我对Javascript有些陌生,似乎不太清楚我的函数到底发生了什么。

背景:我的脚本应该让你给一个元素分配一个"toggler"或"toggled"类,让它们自动链接,所以检查/取消检查toggler会显示/隐藏toggled(我知道有很多库可以做到这一点,但不幸的是,我不能在这种情况下使用它们)

该脚本在页面加载时执行,并在元素中搜索具有类"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"始终设置为切换符数组的长度,而不是递增。例如,第一个和第二个触发器的onclick应该是:

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

它们的实际设置(假设我有5个元素被定义为触发器)是:

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

从我读到的内容来看,我认为这是一个范围界定问题,或者我调用函数的方式,但我没有发现任何有意义的

在创建函数时,不能像那样使用变量i。如果这样做,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);
    }
}

您在这篇博客文章中看到了详细的问题。

原因很复杂。我们定义为事件处理程序的匿名函数从attachEventsToListItems的作用域"继承"变量i,而不是for循环。但是,在执行事件处理程序时,for循环已经完成迭代,并且该函数中的i值已变为4。这里的问题是,我们定义为事件处理程序的函数在执行之前不会为i创建新的作用域。

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

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

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