jQuery устанавливает обратный вызов для дочерних элементов

#javascript #jquery

#javascript #jquery

Вопрос:

Я пытаюсь прикрепить обратный вызов onChange ко всем входным элементам под div #dim . Он выбирает все 3 входных элемента, но возвращает исключение:

 Uncaught TypeError: Object 0 has no method 'change'
  

Это может быть потому, что x может не быть объектом jQuery. Как бы я заставил это работать?

 function registercb() {
    var sel = $("div.dim > input");
    for (x in sel) {
        x.change(function() {
            dosomething();
        });
    }
}
  

Ответ №1:

Вы можете просто сделать:

 function registercb() {
   $("div.dim > input").change(dosomething);               
}
  

Несколько вещей, на которые следует обратить внимание:

  • Внутри этой итерации (не используйте это, смотрите Следующий пункт) x находится элемент DOM, а не объект jQuery, у которого есть .change() метод, вам нужно было бы обернуть его в объект jQuery, подобный $(x) , но опять же, это неправильное решение здесь.
  • Не используйте for(...in...) цикл для итерации объекта (объект jQuery похож на массив), этот тип цикла предназначен для перечисления.
  • Большинство функций jQuery (почти все) выполняются более чем с одним элементом, поэтому просто запустите его на наборе, чтобы повлиять на все элементы, .change() это одна из них.
  • В тех случаях, когда вам действительно нужно выполнить цикл, ознакомьтесь с .each() , так как это значительно облегчит вашу жизнь, не используйте это здесь, это всего лишь пример того, как это будет выглядеть:

Пример:

 function registercb() {
   $("div.dim > input").each(function() {
      $(this).change(dosomething);               
   });
}
  

Ответ №2:

Вам не нужно перебирать элементы. Вы можете думать об объекте jQuery как о хранении коллекции. Когда вы выполняете:

 var sel = $("div.dim > input");
  

Это означает, что sel в нем есть все входные элементы, поэтому, когда вы запускаете метод, подобный change(), это повлияет на все элементы в коллекции. Таким образом, вы можете сделать что-то вроде этого:

 function registercb() {
  $("div.dim > input").change(function(){
    dosomething();
  });
}
  

Бонусные знания: Теперь ваша проблема в том, что, когда вы выполняли for( x in sel ) , вы получаете много ненужного в самом объекте jQuery. Если вы запустите следующий код в Chrome, вы увидите, что он выдает много неожиданного:

 for( x in sel ){
  console.log( x );
}
  

Вместо этого в jQuery есть each , который позволяет вам перебирать то, что вы хотите:

 sel.each(function(index, item){
  console.log(item);
});
  

Вы даже можете использовать его для других целей, что действительно удобно!

 $([1,2,3]).each(function( index item ){
  console.log( item );  // 1,2,3
})
  

Ответ №3:

Предполагая, что у вашего 'dim' div есть идентификатор, а не класс dim , вы можете просто сделать это:

 $("#dim > input").change(function() { dosomething(); });
  

Рабочий пример.

В тексте, на который вы ссылаетесь, #dim тогда как в коде, на который вы ссылаетесь, .dim # выбирает по идентификатору и . выбирает по классу, поэтому, если ваш div находится в формате <div id="dim"> , вы не найдете ни одного совпадающего элемента с div.dim в качестве вашего селектора.