resize触发Uncaught TypeError: el.forEach is not a function报错解决
报错原因
当你将函数直接作为resize事件的回调绑定到window上时,事件触发时浏览器会自动将Resize事件对象作为第一个参数传入回调函数。此时函数形参el接收到的是事件对象而非你预期的DOM元素集合,事件对象不存在forEach方法,因此抛出Uncaught TypeError: el.forEach is not a function错误。
你手动调用handleDisabled(testElements)时能正常运行,是因为此时你主动传入了正确的NodeList类型参数,和事件触发时的传参逻辑完全不同。
修复方法
推荐两种无副作用的修复方式,任选其一即可:
- 方式1:事件绑定时用匿名函数包裹原处理函数,手动传入目标DOM集合作为参数,避免事件默认传参覆盖预期入参
- 方式2:将待操作的DOM集合作为闭包变量直接在处理函数内引用,不需要依赖外部传参,代码更简洁不易出错
修复后完整代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div class="container"> <button class="test">Hey</button> <button class="test">Hey</button> <button class="test">Hey</button> <button class="test">Hey</button> <button class="test">Hey</button> </div> <script type="text/javascript"> const testElements = document.querySelectorAll('.test'); // 方式2写法:直接引用闭包内的DOM集合,无需传参 const handleDisabled = () => { const isDesktop = window.matchMedia('(min-width: 992px)').matches; testElements.forEach(te => { isDesktop ? te.setAttribute('disabled', '') : te.removeAttribute('disabled'); }) } // 事件绑定直接传处理函数即可,不会出现参数错位 window.addEventListener('resize', handleDisabled); // 初始调用 handleDisabled(); </script> </body> </html>
如果要保留原函数的传参设计,只需要修改事件绑定行即可,其他代码不动:
// 方式1写法:匿名函数包裹手动传参 window.addEventListener('resize', () => handleDisabled(testElements));
补充优化:resize事件触发频率非常高,如果逻辑更复杂可以搭配防抖函数使用,避免性能损耗。
内容的提问来源于stack exchange,提问作者Zamu14
相关产品推荐
相关产品推荐

