开发者问题收集

事件监听器给出错误

2015-04-09
319

例如,我有此代码:

<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 不是函数

有人能告诉我为什么会发生这种情况吗?

3个回答
quantityInputs = document.querySelectorAll(".basketQuantity");

首先 quantityInputs NodeList 对象 。因此

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
});

OR

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);
});
Alex
2015-04-09

JavaScript for/in 语句循环遍历对象的属性,因此您的 var i 有时会接收数组 quantityInputs 的属性,例如 length。

只需将循环更改为常规循环,例如 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

Victor
2015-04-09

您正在迭代一个 nodeList:

 quantityInputs = document.querySelectorAll(".basketQuantity");
    [].forEach.call(quantityInputs, function (e) {
        e.addEventListener('click', function () {
            console.log("hello")
        }, false)
    })
Ofer Haber
2015-04-09