Reputation: 1699
I have this code for example:
<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>
When i run it i get the error message:
TypeError: quantityInputs[i].addEventListener is not a function
Could anyone tell me why this is happening?
Upvotes: 0
Views: 322
Reputation: 11255
quantityInputs = document.querySelectorAll(".basketQuantity");
First of all quantityInputs
is the NodeList
object. So
for(var i in quantityInputs){
console.log(i);
}
will return all enumerable properties - from quantityInputs
object and it prototype chain, not only its own (just quantityInputs
enumerable properties). for .. in
will return also length
field and item
enumerable properties from prototype chain and this properties are not DOM nodes and so don't have addEventListener
method.
You must use Object.keys
:
var nodeArray = [].slice.call(document.querySelectorAll(".basketQuantity"));
Object.keys(nodeArray).forEach(function (node) {
// node.addEventListener
});
OR
or for .. in
with hasOwnProperty
check:
quantityInputs = document.querySelectorAll(".basketQuantity");
for(var i in quantityInputs){
if (quantityInputs.hasOwnProperty(i)) {
// quantityInputs[i].addEventListener
}
}
OR
In the future (ES6) you can use in this case for .. of
loop:
var quantityInputs = document.querySelectorAll("basketQuantity");
for (var node of quantityInputs) {
console.log(node.addEventListener);
}
Note(thanks to @Teemu):
Also you have a error in your handler with i
:
quantityInputs[i].addEventListener('change', function(){
console.log(quantityInputs[i]);// return value of quantityInputs last i
});
so better use this
for addEventListener
target:
quantityInputs[i].addEventListener('change', function(){
console.log(this);
});
Upvotes: 1
Reputation: 628
You are iterating on a nodeList:
quantityInputs = document.querySelectorAll(".basketQuantity");
[].forEach.call(quantityInputs, function (e) {
e.addEventListener('click', function () {
console.log("hello")
}, false)
})
Upvotes: 0
Reputation: 5131
The JavaScript for/in statement loops through the properties of an object, so your var i
sometimes receives properties of the array quantityInputs
, like length.
Just change your loop to a convencional, like for (i = 0; i < quantityInputs.length; i++) {...
and it should works:
quantityInputs = document.querySelectorAll(".basketQuantity");
for (i = 0; i < quantityInputs.length; i++) {
quantityInputs[i].addEventListener('change', function(){
console.log('foo');
});
}
Take a look here for more information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
Upvotes: 0