2015-04-09 5 views
0

У меня есть этот код, например:слушатель событий дает ошибку

<html> 
<input class="basketQuantity" type=number>Basket item 1</input> 
<input class="basketQuantity" type=number>Basket item 2</input> 
</html> 

<script> 
quantityInputs = document.querySelectorAll(".basketQuantity"); 
for(var i in quantityInputs){ 
    quantityInputs[i].addEventListener('change', function(){ 
     console.log(quantityInputs[i]); 
    }); 
} 
</script> 

Когда я запускаю это я получаю сообщение об ошибке:

TypeError: quantityInputs[i].addEventListener is not a function

Может кто-нибудь сказать мне, почему это происходит?

+0

В [NodeList] (https://developer.mozilla.org/en-US/docs/Web/API/NodeList) есть несколько свойств, которые учитываются при использовании 'for..in'.Просто используйте цикл 'for' для перебора списка, а не' for..in'. Обратите внимание, что ваш HTML недопустим, [''] (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input) не должен иметь закрывающего тега. – Teemu

+0

Неправильная установка для вашего цикла. В вашем случае «i» - это строка. Итак, что вы делаете, это: quantityInputs ["0"] и quantityInputs ["1"]. Вместо целых величинInputs [0] и quantityInputs [1]. – Hoyen

+0

После того, как вы работаете в цикле, [здесь] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) является решением вашей второй проблемы. – Teemu

ответ

1
quantityInputs = document.querySelectorAll(".basketQuantity"); 

Прежде всего quantityInputs является NodeList object. Так

for(var i in quantityInputs){ 
    console.log(i); 
} 

вернет все перечисляемые свойства - от quantityInputs объекта и его прообразами цепи, не только свои собственные (всего quantityInputs перечислимых свойств). for .. in вернет также length поле и item перечислимые свойства из цепочки прототипов, и эти свойства не являются узлами DOM и поэтому не имеют метода addEventListener.

Вы должны использовать Object.keys:

var nodeArray = [].slice.call(document.querySelectorAll(".basketQuantity")); 

Object.keys(nodeArray).forEach(function (node) { 
    // node.addEventListener 
}); 

ИЛИ

или for .. in с hasOwnProperty проверки:

quantityInputs = document.querySelectorAll(".basketQuantity"); 
for(var i in quantityInputs){ 
    if (quantityInputs.hasOwnProperty(i)) { 
     // quantityInputs[i].addEventListener 
    } 
} 

ИЛИ

В будущем (ES6), вы можете использовать в этом случае for .. of цикл:

var quantityInputs = document.querySelectorAll("basketQuantity"); 

for (var node of quantityInputs) { 
    console.log(node.addEventListener); 
} 

Примечание (благодаря @Teemu):

Также у Вас есть ошибка в обработчике с i:

quantityInputs[i].addEventListener('change', function(){ 
    console.log(quantityInputs[i]);// return value of quantityInputs last i 
}); 

, так что лучше использовать this для addEventListener цели:

quantityInputs[i].addEventListener('change', function(){ 
    console.log(this); 
}); 
+0

@Teemu, спасибо, добавьте это – Pinal

0

Вы итерация на Nodelist:

quantityInputs = document.querySelectorAll(".basketQuantity"); 
    [].forEach.call(quantityInputs, function (e) { 
     e.addEventListener('click', function() { 
      console.log("hello") 
     }, false) 
    }) 
+0

Обратите внимание, что OP требует правильного значения 'i' в обработчике событий, а не« hello ». – Teemu

+0

Вопрос не в написании «привет», а не в «foo» или иначе, это о привязке события к элементу. –

0

JavaScript для/в заявлении перебирает свойство объекта, так что ваш var i иногда получает свойство массива quantityInputs, как длина.

Просто измените петлю на convencional, как for (i = 0; i < quantityInputs.length; i++) {... и должна работать:

quantityInputs = document.querySelectorAll(".basketQuantity"); 
for (i = 0; i < quantityInputs.length; i++) { 
    quantityInputs[i].addEventListener('change', function(){ 
     console.log('foo'); 
    }); 
} 

Посмотрите здесь для получения дополнительной информации: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

+0

Это дает мне ту же ошибку, если я использую этот способ – Adam

+0

http://jsfiddle.net/nLze6kod/ – Victor

+1

Это всего лишь пример, но если вам нужно 'quantityInputs [i]', то 'this' эквивалентно в этом контексте, поэтому вы можете использовать 'console.log (this)' – Victor

Смежные вопросы