Javascript - 在声明异步函数时使用变量的值(直接,而不是通过引用)

时间:2011-10-11 01:36:46

标签: javascript events variables function-declaration

好吧,

我有一些看起来像这样的东西:

for (j = 0; j < btnArr.length; j++)
{
    var btn = document.createElement("button");
    btn.addEventListener("click", function() { press(this, j) }, false);
    div.appendChild(btn);
}

我的问题是,由于事件发生在较晚的时间,j已经在事件的功能被触发时已经改变了值。我希望函数在声明函数时直接使用j的值,而不是对j本身的引用。

如果addEventListener的第二个参数是一个字符串,它将如下所示:

btn.addEventListener("click", "function() { press(this, " + j + ") }", false);

有谁知道是否可能,以及如何做到这一点?

我试着搜索一下,但是找不到任何相关内容,因为只用几句话就难以正确描述问题。

顺便说一句,这是针对Greasemonkey脚本的,因此使用.addEventListener()代替.onclick = (...)

4 个答案:

答案 0 :(得分:2)

你只需打破上下文。它可以通过多种方式完成,但Function.bind是最优雅的恕我直言。由于你在Firefox中,绑定应该在那里。

for (j = 0; j < btnArr.length; j++)
{
    var btn = document.createElement("button");
    btn.addEventListener("click", function(value) { press(this, value) }.bind(btn, j), false);
    div.appendChild(btn);
}

对于替代方法,编写一个返回处理程序的函数。

for (j = 0; j < btnArr.length; j++)
{
    var btn = document.createElement("button");
    btn.addEventListener("click", getHandler(j), false);
    div.appendChild(btn);
}

function getHandler(j) {
    return function() { press(this, j) };
}

另一个选择是向button元素添加属性。

for (j = 0; j < btnArr.length; j++)
{
    var btn = document.createElement("button");
    btn.myValue = j;
    btn.addEventListener("click", function() { press(this, this.myValue); }, false);
    div.appendChild(btn);
}

答案 1 :(得分:1)

你已经解决了听众关闭时代的问题。您可以使用:

btn.addEventListener("click", (function(x) {
                                 return function(){
                                    press(this, x) 
                                 };
                               }(j)), false);

并且为了避免某些浏览器中的内存泄漏,请在完成后删除对该元素的引用:

btn = null;

打破关闭。 SO上有很多答案。您可以使用 bind ,但并非所有浏览器都可以使用。

答案 2 :(得分:1)

btn是一个对象,您可以随时添加自己的属性并在以后访问它们:

for (var j = 0; j < btnArr.length; j++)
{
    var btn = document.createElement("button");
    btn.index = j;
    btn.addEventListener("click", function() { press(this, this.index) }, false);
    div.appendChild(btn);
}

请参阅http://jsfiddle.net/Kai/Y2KaZ/

答案 3 :(得分:0)

你不能像那样改变词汇范围的规则。你可以做的是使用这样一个事实:如果你创建一个帮助函数,它将很乐意为你创建一个新的绑定。

function make_handler(i){
    //you can use j here as well instead of i
    //I'm just avoiding shadowing for didactic reasons...
    return function() { press(this, i) };
}

for (j = 0; j < btnArr.length; j++)
{
    var btn = document.createElement("button");
    btn.addEventListener("click", make_handler(j), false);
    div.appendChild(btn);
}