是否需在document上调用removeEventListener?含代码场景的必要性与可行性问询
关于document上addEventListener移除的疑问解答
嘿,我来帮你理清这两个问题:
1. 是否有必要在document对象上调用removeEventListener方法?
这得分具体场景来看:
- 如果这个监听是页面整个生命周期都需要的功能(比如全局的键盘快捷键监听、页面滚动的全局处理),那完全没必要移除——它会跟着document的存在一直生效,直到页面卸载,不会有什么问题。
- 但如果这个监听只是临时需求(比如某个弹窗打开时需要监听点击,弹窗关闭后就不需要了),那移除就非常有必要:
- 避免不必要的性能消耗:没用的监听还会一直触发,每次DOM变化、事件触发都跑一遍逻辑,浪费资源;
- 防止逻辑冲突:后续的代码可能和这个旧监听的逻辑打架;
- 避免内存泄漏:如果监听函数里引用了一些会被销毁的对象(比如组件实例、弹窗DOM),document会一直持有这个函数的引用,导致相关对象没法被垃圾回收。
2. 你提供的代码中,能否/是否需要移除这个DOMNodeInserted监听?
首先先把你写的代码整理成可阅读的格式(原代码有语法错误,我补全了缺失的括号):
getFavTable = () => { document.addEventListener('DOMNodeInserted', () => { if (document.querySelector('#todayfavtable') != null) { document.querySelector('#todayfavtable').scrollIntoView(); window.scrollBy(0, -50); // 原代码这里多了个offsetTop,应该是笔误? } else { window.scrollTo(0, 0); } }); }
能不能移除?
很遗憾,你现在的写法没法移除。因为addEventListener接收的是一个匿名箭头函数,而removeEventListener必须传入和添加时完全相同的函数引用才能找到对应的监听。匿名函数没有办法被再次引用,所以你根本没法用removeEventListener定位到它。
要能移除的话,得把函数抽成具名函数,比如:
// 先定义具名函数 function handleFavTableInsert() { const favTable = document.querySelector('#todayfavtable'); if (favTable != null) { favTable.scrollIntoView(); window.scrollBy(0, -50); } else { window.scrollTo(0, 0); } } getFavTable = () => { document.addEventListener('DOMNodeInserted', handleFavTableInsert); } // 之后需要移除的时候调用 // document.removeEventListener('DOMNodeInserted', handleFavTableInsert);
是否需要移除?
非常有必要!你的逻辑是等#todayfavtable插入DOM后执行滚动操作,那一旦这个元素出现并完成滚动,这个监听就完全没用了。如果不移除,它会在每次有DOM节点插入时都触发判断——比如页面加载其他内容、动态渲染组件的时候,都会跑一遍这个逻辑,既浪费性能,还可能在某些情况下触发不必要的滚动。
优化后的代码可以在完成操作后立刻移除监听:
function handleFavTableInsert() { const favTable = document.querySelector('#todayfavtable'); if (favTable != null) { favTable.scrollIntoView(); window.scrollBy(0, -50); // 完成操作后立刻移除,避免后续触发 document.removeEventListener('DOMNodeInserted', handleFavTableInsert); } else { window.scrollTo(0, 0); } } getFavTable = () => { document.addEventListener('DOMNodeInserted', handleFavTableInsert); }
内容的提问来源于stack exchange,提问作者Eugenios
相关产品推荐
相关产品推荐

