【问题标题】:jQuery - why can't I bind events to elements in a loop?jQuery - 为什么我不能将事件绑定到循环中的元素?
【发布时间】:2012-03-06 11:45:54
【问题描述】:

这是我的代码:

  var b = $(slipStream.conf.mainVis).find('p#prev');
  b.click(function() {
    slipStream.slideLeft();
        return false;
  });

  b = $(slipStream.conf.mainVis).find('p#next');
  b.click(function() {
    slipStream.slideRight();
        return false;
  });

  b = $(slipStream.conf.controls).find('li img');
  console.log(b);
  for (var l in b) {
        l.click(function() {
              var visIndex = l.index();
              console.log(visIndex);
        });
  };

前两个绑定通过,没问题。但是我不能遍历一个集合并将某些东西绑定到每个成员? (控制台告诉我“l.click 不是函数。”)这是 jQuery 的限制还是我的代码关闭了?不过,这似乎是这样做的方法......

【问题讨论】:

  • 你可以试试$(l).click(function(){ ... });吗?
  • 为什么不使用$.each(b)b.each() 来代替?请参阅:api.jquery.com/jQuery.eachapi.jquery.com/each
  • @m90 大多数时候,如果你在做 $b.each() 你做错了......

标签: javascript binding jquery


【解决方案1】:

当您枚举一个 jQuery 对象时,被枚举的值是实际的 DOM 节点,而不是 jQuery 包装器。因此,它们没有click 方法,但您可以再次包装它们以获得所有常用功能。

当然这不是必需的,因为您可以直接从初始 jQuery 实例附加一个包装器:

$(slipStream.conf.controls).find('li img').click(function() {
    var visIndex = $(this).index();
    console.log(visIndex);
});

【讨论】:

  • 上面的第一个代码将不起作用,因为它无法修复循环变量关闭问题。
  • @Alnitak:确实;通过将index 调用移出事件处理程序来修复它。感谢您的发现。
  • 不,这仍然无法解决它 - visIndex 必须绑定到一个范围,而您的修改后的代码仍然没有这样做。该错误仅限于循环变量,它适用于任何变量更改内部外部的回调。
【解决方案2】:

这是经典的“循环变量在回调中不能正常工作”的错误。

在调用回调时,您的变量 l 不再具有最初提供的值 - 它具有在最后一次循环中分配的任何最终值。

[FWIW,l 实际上不是一个 jQuery 对象,所以你必须将它包装起来 - $(l) 才能将它与 jQuery 一起使用]

对循环错误的通常修复是创建一个额外的闭包返回一个函数绑定到当前值:

for (var l in b) {   // NB: don't use `for ... in ...` on array-like objects!
    var make_cb = function(n) {
         return function() {
              var visIndex = $(n).index();
              console.log(visIndex);
         }
    }
    $(l).click(make_cb(l));
};

幸运的是,您根本不需要循环 - 您可以让 jQuery 自动将回调添加到每个元素:

b = $(slipStream.conf.controls).find('li img');
b.click(function() {
    var visIndex = $(this).index();
    console.log(visIndex);
});

【讨论】:

    【解决方案3】:

    问题可能出在forloop。 .click 是 jQuery 的一部分,因此您必须确保它是在使用 jQuery 包装的元素上调用的。

    $.each(b, function (index, element) {
       $(element).click(function() {
       });
    };
    

    【讨论】:

    • .index()一样,因为l不是一个jQuery集合。
    【解决方案4】:

    使用each(),您可以遍历一组 jQuery 对象:

    $(slipStream.conf.controls).find('li img').each(function(){
        $(this).click(function() {
            var visIndex = $(this).index();
            console.log(visIndex);
        });
    });
    

    $(this) 将匹配集合中当前索引的对象。

    【讨论】:

    • .click() 在提供的 jQuery 对象上执行隐式 .each()
    猜你喜欢
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    相关资源
    最近更新 更多