深挖掘:javaScript addEventListener 给DOM绑定事件,移除DOM元素后,事件函数会怎样

261 阅读2分钟

答案公布

在js开发中,使用addEventListener API为DOM元素绑定事件(比如鼠标事件),当我们在页面

上移除该DOM元素,没有使用removeEventListener解绑事件, 该元素绑定的事件函数就

不会解绑,而且未被js垃圾回收机制回收,依旧占用js内存!

Demo例子验证

啥也不说,先看demo关键代码

<!-- 省略css代码 -->
<div class="box1 flex" id="box1">
   Box1
   <div class="box2 flex" id="box2">
     Box2 <div class="box3 flex" id="box3">Box3</div>
   </div>
</div>
<br />
<button onclick="removeNode()">删除Box2,Box3</button>   
<br />   
<br />   
<button onclick="removeNodeEventBox2()">remove Box2的绑定事件</button>

上述代码,展示的页面效果

页面有3个层层嵌套的div,由外到里Box1,Box2, Box3,

给每个div绑定click事件, 代码如下:

let box1 = null   
let box2 = null   
let box3 = null       
window.onload = function() {       
   box1 = document.getElementById('box1')          
   box2 = document.getElementById('box2')      
   box3 = document.getElementById('box3')      
   /* false 事件冒泡 ture 事件捕获 */     
   const bl = false
   box1.addEventListener('click', fn1, bl )           
   box2.addEventListener('click', fn2, bl )       
   box3.addEventListener('click', fn3, bl )  
}
 
/* 事件函数 */     
function fn1 () {    console.log('box1')  }  
function fn2 () {    console.log('box2')  }  
function fn3 () {    console.log('box3')  }

绑定事件成功,点击Box3,触发事件冒泡,控制台显示box3, box2, box3

然后点击'删除Box2,Box3',  执行removeNode 事件, 代码和效果如下

/* 删除Box2,Box3 按钮 执行 */    
function removeNode() {      
  box2.parentNode.removeChild(box2)      
  setTimeout(() => {        
     console.log('------删除Box2,Box3, 延时1秒---------')        
     /* 模拟点击 Box3 */        
     box3.click()      
   }, 1000)    
}

执行说明:

页面已经成功删除Box2, Box3两个DOM元素,删除成功后,延时1秒执行Box3的click事

件,控制台打印‘box3’ 'box2'。

因此说明使用addEventListener API为DOM元素绑定事件(如鼠标事件),当我们在页面上移

除****该DOM元素, 该元素绑定的事件函数依旧可以执行,事件函数fn2, fn3仍被引用,不会释

放。由于Box2在页面上删除不存在,事件冒泡的链路被打断,所以不会执行Box1的click事件fn1。

如果在删除Box2前,我们使用removeEventListener移除绑定事件, 后执行删除Box2,Box3,代码和效果如下

/* remove Box2的绑定事件 按钮 执行 */    
function removeNodeEventBox2() {      
   box2.removeEventListener('click', fn2 )    
}

Box2绑定的事件被移除,Box3绑定的事件没有移除。

总结

addEventListener 和 removeEventListener 在我们开发中经常用来给DOM元素绑定事件,当

我们要在页面document上移除DOM,别忘了先清除其绑定的事件,防止内存泄漏,和产生莫

名其妙的bug。