【问题标题】:Late binding onclick event后期绑定 onclick 事件
【发布时间】:2023-03-20 19:10:01
【问题描述】:

以下我的 javscript 的一部分(使用 jquery)。

list = ['a', 'b', 'c'];
for(var i = 0 ; i< list.length ; i++) {
   $("<a>click here</a>").
      click(function(){
          foo(list[i]);
      }).
      appendTo('#sometag');
}
function foo(val) {
    console.log(val);
}

无论您点击哪个标签,总是打印 c。如何打印正确的值???
似乎它正在使用 i=3 的最后一个值,因此总是评估 oc

【问题讨论】:

  • 旁注,int i = 0 是错误的。试试var i = 0 或只是i = 0
  • 从技术上讲,您上面的代码甚至没有记录“c”,它记录了“未定义”。 jsfiddle.net/j08691/9Th9G
  • 老兄这只是一个示例代码。人家已经回答了。相反,如果发现高于此的错误,请在此下方放置一些时间。
  • 老兄,按照你说的做的发布代码。当您发布不准确的代码时,它会浪费每个人的时间来调试您的代码。

标签: javascript jquery closures


【解决方案1】:

您需要一个 closure 新范围,因为在触发事件处理程序之前迭代完成,所以当点击发生时,循环已经完成并且i 是它设置的最后一个值,新的作用域将 i 的值保留在该作用域的本地

list = ['a', 'b', 'c'];

for(var i=0; i<list.length; i++) {

   (function(j) {

       $("<a>click here</a>").click(function(){
          foo(list[j]);
       }).appendTo('#sometag');

   }(i));

}

function foo(val) {
    console.log(val);
}

另一种选择是添加更多 jQuery

list = ['a', 'b', 'c'];

$.each(list, function(index, item) {
    $("<a />", {text : 'click here',
                on   : {
                    click : function() {
                        foo(item);
                    }
                }
    }).appendTo('#sometag');
});

function foo(val) {
    console.log(val);
}

【讨论】:

  • 我从来没有想过使用自执行函数来形成一个闭包。好主意。这比在别处定义的函数中形成闭包更好吗?
  • 事件处理程序已经是一个闭包。解决方案是通过执行一个函数来创建一个新范围,而不是通过创建另一个闭包。
  • @FelixKling - 是的,但是当你只说“关闭”而不是范围时,大多数人往往会更好地理解它。
【解决方案2】:

创建一个闭包以在函数执行时为特定迭代保留 i 的值,如果没有闭包 i 保持在作用域内,则会导致所有创建的函数最终具有最后一次迭代的值:

var list = ['a', 'b', 'c'];
for(var i = 0 ; i< list.length ; i++) {
   var func = createFoo(list[i]);
   $("<a>click here</a>").
      click(func).
      appendTo('#sometag');
}
function createFoo(value){
    return function(){
        foo(value);
    };
}
function foo(val) {
    console.log(val);
}

JS 小提琴: http://jsfiddle.net/5dUgw/

另请注意您需要将int 更改为var,因为这是JS。

【讨论】:

  • 事件处理程序已经是一个闭包。解决方案是通过执行一个函数来创建一个新范围,而不是通过创建另一个闭包。
猜你喜欢
  • 1970-01-01
  • 2015-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多