Javascript事件监听器的匿名函数是否保持返回相同的值?

时间:2013-07-14 07:39:37

标签: javascript html events javascript-events

嘿,我正在编写一个代码,它基本上添加了一个事件监听器,它用一个dom对象id的片段来调用一个函数,但是每次我用一个监听器点击一个对象它只是给了我相同的值,无论我用什么对象点击这里是我的代码

//add events
for (a=0; a<=tab_array.length-3; a++)
{
alert(a);
document.getElementById("mini_"+a).addEventListener("click",function(){open_tab(a)},false); 
}


function open_tab(e)
{
//change across settings ect
alert("tab "+e+" clicked");
}

我意识到它可能与指针有关,事实上它使用匿名函数而不是指示传递a,但我只是不知道该怎么做

2 个答案:

答案 0 :(得分:2)

你的猜测是正确的。您看到的行为是因为您的范围。

点击链接后,javascript会传递当前值a 此值为tab_array.length-2,而不是循环运行a期间的值0, 1 ...

要保持a的值,您必须在新范围(闭包)中创建新变量。例如。 e

for (a=0; a<=tab_array.length-3; a++)
{
  function(e){
    document.getElementById("mini_"+e).addEventListener("click",function(){open_tab(e)},false); 
  }(a));
}

另一种方法是编写一个函数,在自己的作用域内返回你的处理程序:

//add events
for (a=0; a<=tab_array.length-3; a++)
{
  alert(a);
  document.getElementById("mini_"+a).addEventListener("click", open_tab(a) ,false); 
}

function open_tab(e) {
  return function() {
    //change across settings ect
    alert("tab "+e+" clicked");
  }
}

参见 my fiddle Closure guide

答案 1 :(得分:0)

@ jantimon的代码示例都是解决此问题的好方法,但我想建议第三种方法。而不是自调用函数表达式或返回函数的函数,考虑一个普通的命名函数:

for( var i = 0;  i <= tab_array.length - 3;  ++i ) {
    setupTab( i );
}

function setupTab( i ) {
    var element = document.getElementById( 'mini_' + i );
    element.addEventListener( 'click', function() {
        open_tab( i );
    }); 
}

这与自调用函数基本相同,但具有以下优点:

  1. 熟悉。这只是一个普通的函数调用。
  2. 更简单,更简单的循环体。
  3. 使用自调用函数,函数参数和传入的实际参数位于函数的两端(开头的参数,结尾的参数)。一个单独的功能可以避免这种情况。
  4. 这些只是次要的优势,可以肯定 - 任何这些方法都可以解决问题。但我确实喜欢这种方法的清晰度。