如何在javascript(jQuery)中分配迭代数组的事件回调

Jor*_*enB 4 javascript iteration jquery events

我正在通过javascript生成一个无序列表(使用jQuery).每个listitem必须为"click"事件接收自己的事件监听器.但是,我无法将正确的回调附加到正确的项目上.(剥离的)代码示例可能会略微清楚:

for(class_id in classes) {
    callback = function() { this.selectClass(class_id) };
    li_item = jQuery('<li></li>')
                .click(callback);
}
Run Code Online (Sandbox Code Playgroud)

实际上,这次迭代还有更多,但我认为这与问题无关.在任何情况下,发生的事情是回调函数似乎被引用而不是存储(和复制).最终结果?当用户点击任何列表中的项目,它将始终执行的动作最后 class_id的在classes阵,因为它使用存储在功能callback在说具体点.

我找到了肮脏的解决方法(比如href在封闭的a元素中解析属性),但我想知道是否有办法以"干净"的方式实现我的目标.如果我的方法令人恐惧,请说出来,只要你告诉我原因:-)谢谢!

Pet*_*ley 8

这是一个经典的"你需要一个关闭"的问题.这是它通常如何发挥作用.

  1. 迭代一些值
  2. 在使用迭代变量的迭代中定义/分配函数
  3. 您了解到每个函数仅使用上一次迭代中的值.
  4. WTF?

再一次,当你看到这种模式时,它会立即让你想到"封闭"

扩展你的例子,这是你如何放入一个闭包

for ( class_id in classes )
{
  callback = function( cid )
  {
    return function()
    {
      $(this).selectClass( cid );
    }
  }( class_id );
  li_item = jQuery('<li></li>').click(callback);
}
Run Code Online (Sandbox Code Playgroud)

但是,在jQuery的这个特定实例中,你不应该需要一个闭包 - 但我必须询问你的变量的性质classes- 是一个对象吗?因为您使用for-in循环进行迭代,这表示对象.对我而言,它引出了一个问题,为什么不将它存储在一个数组中呢?因为如果你是,你的代码可能就是这样.

jQuery('<li></li>').click(function()
{
  $(this).addClass( classes.join( ' ' ) );
});
Run Code Online (Sandbox Code Playgroud)