0

好吧,

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

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

4 回答 4

2

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

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);
}
于 2011-10-11T01:43:00.457 回答
1

您已经解决了听众中关闭的古老问题。您可以使用:

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

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

btn = null;

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

于 2011-10-11T01:45:35.217 回答
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/

于 2011-10-11T01:47:33.103 回答
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);
}
于 2011-10-11T01:44:52.720 回答