如何修复JS中.addEventListener is not a function及onclick设置报错
报错成因
document.querySelectorAll()返回的是类数组结构的NodeList集合,而非单个DOM元素。你直接对btn这个集合调用只有DOM元素才具备的addEventListener方法,自然会触发addEventListener is not a function报错;同理直接给集合赋值onclick属性,也会抛出无法设置属性的异常。- 你用
slc(".enter_1")、slc(".result_")获取的也是NodeList集合,直接取.value、.innerHTML都无法正常读写对应元素的属性,必须指定集合索引才能获取到实际的DOM节点。
修复方案
核心逻辑是:单个唯一元素直接用querySelector获取,匹配多个的按钮遍历集合逐个绑定事件,通过data-*属性区分运算类型简化代码。
修正后的完整可运行代码如下:
<!-- try run this --> <div class="input_wrpr"> <input class="enter_1" type="number" /> <input class="enter_2" type="number" /> <button data-combine="plus" class="combine_ plus" type="button"> + </button> <button data-combine="minus" class="combine_ minus" type="button"> - </button> <button data-combine="multi" class="combine_ multi" type="button"> * </button> <button data-combine="divi" class="combine_ divi" type="button"> / </button> <p class="result_"></p> </div> <script> (function () { "use strict"; // 单个元素用querySelector,多个元素用querySelectorAll const $ = selector => document.querySelector(selector); const $$ = selector => document.querySelectorAll(selector); const view = $(".result_"), btns = $$(".combine_"), input1 = $(".enter_1"), input2 = $(".enter_2"); // 运算逻辑映射 const calcMap = { plus: (a, b) => a + b, minus: (a, b) => a - b, multi: (a, b) => a * b, divi: (a, b) => a / b }; // 遍历所有按钮绑定事件 btns.forEach(btn => { btn.addEventListener("click", (e) => { const num1 = parseInt(input1.value) || 0; const num2 = parseInt(input2.value) || 0; const op = e.currentTarget.dataset.combine; view.innerHTML = calcMap[op](num1, num2); // 清空输入框 input1.value = ""; input2.value = ""; }); }); })(); </script>
额外说明:原代码中按钮的type是submit,点击会默认提交页面刷新,这里修改为type="button"避免无意义的页面刷新。
内容的提问来源于stack exchange,提问作者Noob
相关产品推荐
相关产品推荐

