将onmouseenter设置为带参数的函数

时间:2012-06-28 03:33:58

标签: javascript function-pointers onmouseover

我试图为ready回调中元素的所有子div设置onmouseenter函数。所以身体的负荷是

    function ready(){
      for(var i=0;i<document.getElementById("pieces").childNodes.length;i++){
    var n=document.getElementById("pieces").childNodes.item(i);
    n.onmouseenter=function(){showBorder(n);};
    n.onmouseleave=hideBorder;
     }
    }

但是所有获取其onmouseenter函数的div都使用了在循环结束时出现的n值。我希望每个onmouseenter在设置回调时使用n的值。

我该怎么办? 提前致谢

2 个答案:

答案 0 :(得分:1)

问题是处理程序绑定到同一个n。因此,更改n会更改所有处理程序的n

您可以通过将n传递给每次迭代执行的立即函数来“本地化”n。这使得每个处理程序的n绑定到立即函数的n,而不是函数n的{​​{1}}

ready

答案 1 :(得分:0)

JavaScript具有函数级范围,因此在{{1}中声明变量n(但 document.getElementById('pieces').childNodes.item(i)n的赋值) }} loop实际上被提升到for函数的顶部。

要理解这一点,假设您的代码实际上是这样编写的,因为这是JavaScript引擎实际解释它的方式:

ready

function ready() { var i, n; for (i = 0; i < document.getElementById('pieces').childNodes.length; i++) { n = document.getElementById("pieces").childNodes.item(i); n.onmouseenter = function () { showBorder(n); }; n.onmouseleave = hideBorder; } } function () { showBorder(n); }的{​​{1}}属性的赋值创建了一个闭包,当该匿名函数实际执行时,它将访问范围内的任何和所有数据。创建的时间,即调用n函数的时间。因此,这些onmouseenter方法中的每一个都将引用变量ready,该变量在onmouseenter执行完成时具有等于n的值

我建议使用以下代码段:

ready
  1. 声明范围顶部的所有变量,这样就不会在函数上下文中混淆它们的范围。
  2. 查找document.getElementById('pieces').childNodes.length 一次并将该内存位置分配给function ready() { var pieces, i, l, n; pieces = document.getElementById('pieces').childNodes; for (i = 0, l = pieces.length; i < l; i++) { n = pieces.item(i); n.addEventListener('mouseover', (function (m) { showBorder(m); })(n), false); n.addEventListener('mouseout', hideBorder, false); } } 变量,以避免每次需要引用该组节点时进行另一次查找。
  3. document.getElementById('pieces').childNodes循环中的比较语句在每次迭代时执行,因此不是查找pieces,而是重复将其分配给变量for一次并引用每次都是变量。
  4. 在大多数情况下,使用DOM元素的pieces.length方法是分配事件处理程序的最糟糕方式,因为你只能在任何地方注册给定DOM元素的单个函数时间。 l方法是分配处理程序的首选方法,除非您希望用户使用旧版本的Internet Explorer,而不是on<event>方法。
  5. addEventListenerattachEvent事件不是标准DOM事件,而是Microsoft为旧版Internet Explorer添加的自定义事件。它们被添加到DOM Level 3规范中,Firefox和Opera引入了对这些事件的支持,但Webkit仍然不支持它们。