Почему я не могу связать события с элементами в цикле? - PullRequest
0 голосов
/ 06 марта 2012

Вот мой код:

  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 или мой код отключен?Похоже, это был бы способ сделать это, хотя ...

Ответы [ 4 ]

3 голосов
/ 06 марта 2012

Когда вы перечисляете объект jQuery, перечисляемые значения являются фактическими узлами DOM, а не оболочками jQuery. Поэтому у них нет метода click, но вы можете снова обернуть их, чтобы получить все обычные функции.

Конечно, в этом нет необходимости, потому что вы можете просто прикрепить обертку прямо из исходного экземпляра jQuery:

$(slipStream.conf.controls).find('li img').click(function() {
    var visIndex = $(this).index();
    console.log(visIndex);
});
1 голос
/ 06 марта 2012

Это классическая ошибка "переменные цикла не работают должным образом в обратных вызовах".

Ваша переменная 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);
});
0 голосов
/ 06 марта 2012

С each() вы можете перебирать набор объектов jQuery:

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

$(this) будет соответствовать индексируемому в данный момент объекту из коллекции.

0 голосов
/ 06 марта 2012

Может быть, проблема в цикле for. .click является частью jQuery, поэтому вы должны быть уверены, что он вызывается для элемента, который является оберткой с jQuery.

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