页面JS代码中spans[i]触发Uncaught TypeError错误,请求排查原因
错误根源与修复方案
你的问题不是spans[i]不存在,而是事件回调的传递方式错误,导致函数被提前执行并抛出异常。
问题分析
在setSpanListeners函数的循环中,你直接调用了setBckCol('#F9E79F')并把结果传给addEventListener:
spans[i].addEventListener('click', setBckCol('#F9E79F'));
这会触发两个核心问题:
setBckCol会立即执行,而非等待点击事件触发。此时函数的this指向不是当前span元素(非严格模式下指向window,严格模式下为undefined),执行this.style.backgroundColor = col时就会抛出Cannot read properties of undefined (reading 'style')的错误——你看到的报错信息是浏览器对异常的链式表述。- 函数执行后返回
undefined,相当于给addEventListener传递了一个无效的回调。
此外还有两个小问题:
- CSS中
display: fit-content不是标准属性,建议用inline-block实现hover时背景自适应宽度的效果 - 第二个for循环中的
i未声明,会成为全局变量,建议用let声明
修复方案
要传递带参数的事件回调,需要用匿名函数包装或bind方法绑定this和参数:
方法1:匿名函数包装
function setSpanListeners() { var spans = document.querySelectorAll('span'); for(let i = 0; i < spans.length ;i++) { spans[i].addEventListener('click', function() { setBckCol.call(this, '#F9E79F'); }); } }
方法2:使用bind绑定
function setSpanListeners() { var spans = document.querySelectorAll('span'); for(let i = 0; i < spans.length ;i++) { spans[i].addEventListener('click', setBckCol.bind(spans[i], '#F9E79F')); } }
完整修复代码
<!DOCTYPE html> <html> <head> <style> span { font-family:Verdana, Arial, sans-serif; font-size:14px; display: inline-block; /* 替换fit-content实现自适应宽度 */ } span:hover { background-color: lightgrey; cursor:pointer; } </style> </head> <body> <span>3.1415</span> </body> <script> function setBckCol(col) { this.style.backgroundColor = col; } function setSpanListeners() { var spans = document.querySelectorAll('span'); for(let i = 0; i < spans.length ;i++) { spans[i].addEventListener('click', function() { setBckCol.call(this, '#F9E79F'); }); } } const nodeList = document.querySelectorAll("span"); for (let i = 0; i < nodeList.length; i++) { // 声明let i避免全局污染 nodeList[i].style.backgroundColor = "red"; } setSpanListeners(); </script> </html>
关键说明
addEventListener的第二个参数需要传递函数引用,而不是函数执行的结果。直接写setBckCol('#F9E79F')会立即执行函数,导致逻辑完全偏离预期。通过call或bind可以确保setBckCol中的this指向当前被点击的span元素,从而正确修改其样式。
内容的提问来源于stack exchange,提问作者Svea
相关产品推荐
相关产品推荐

