React中如何为getElementsByClassName获取的div添加addEventListener滚动监听并解决TS报错
修复TypeScript ESLint报错:addEventListener不存在于HTMLCollectionOf类型
报错根因
你当前代码的报错提示为:
Property 'addEventListener' does not exist on type 'HTMLCollectionOf'.ts
- 触发原因非常明确:调用
getElementsByClassName获取到的返回值是HTMLCollectionOf<Element>类型,即所有匹配指定类名的元素组成的集合,不是单个DOM节点。 - 集合类型本身没有
addEventListener方法,因此会触发TS类型校验错误。即使实际页面上只有1个匹配类名的元素,TypeScript的类型定义也不会自动将集合识别为可绑定事件的单节点。
具体修复方案
方案1:使用单节点选择器(推荐)
把原本获取类名集合的代码,替换为querySelector方法。该方法会返回DOM中第一个匹配选择器的单个元素,其类型本身支持绑定事件:
将原有获取元素的代码:
const element = document .getElementById('dialog') ?.getElementsByClassName('MuiDialog-paperScrollPaper');
修改为:
const element = document .getElementById('dialog') ?.querySelector('.MuiDialog-paperScrollPaper');
修改后element的类型为HTMLElement | null,可正常调用addEventListener,不会触发类型报错。
方案2:从元素集合中提取目标节点
如果必须保留getElementsByClassName的调用方式,需要手动从返回的集合中通过索引取出第一个匹配的元素:
const element = document .getElementById('dialog') ?.getElementsByClassName('MuiDialog-paperScrollPaper')[0];
React 场景适配注意事项
在useEffect内绑定的全局DOM事件,必须在组件卸载时执行清理,否则会造成内存泄漏。完整的可运行实现如下:
useEffect(() => { const element = document .getElementById('dialog') ?.querySelector('.MuiDialog-paperScrollPaper'); const onScroll = () => { console.log('Scrolled'); }; element?.addEventListener('scroll', onScroll); // 组件卸载时移除事件监听 return () => { element?.removeEventListener('scroll', onScroll); }; }, []);
补充提示:MUI Dialog默认通过Portal在根组件树外渲染DOM,需确认
useEffect执行时目标DOM已完成挂载,避免出现元素获取为null的问题。
内容的提问来源于stack exchange,提问作者meez
相关产品推荐
相关产品推荐

