关于mouseenter和mouseover的冒泡阶段和捕获阶段相关问题的大汇总
写在前面,这里是对mouseenter、mouseleave、mouseover、mouseout四个事件的原理做一个总结,方便大家在检索问题的时候,能够看到,给大家提供一个理解的思路;当然也希望老师可以看一下,如果我的理解哪里有问题,还请指出
原理总结
1、冒泡阶段执行顺序由内向外;捕获阶段执行顺序有外向内
2、mouseenter和mouseleave冒泡阶段是不冒泡的,简单来说就是,子元素触发事件的时候不会引起父元素的事件监听;而mouseover和mouseout是可以冒泡的
3、四个事件的捕获阶段都是可以捕获的;所以,如果是监听捕获阶段的mouseenter的话,当子元素触发事件的时候会引起父元素的事件监听
4、mouseenter和mouseleave需要把盒模型想成是立体的,表面上来看,子元素占据了父元素的一些区域,但从结构上来看的话,子元素依然还在父元素的区域内;mouseover和mouseout需要把盒模型想成是平面的,子元素占据了父元素的区域后就不再算是父元素区域了
举例说明
监听鼠标从A区域(子元素)移动到B区域(A的父元素、C的子元素)的冒泡阶段
对于mouseleave来说,因为不会冒泡,所以只能触发A区域的离开事件,并不会触发B、C区域的离开事件;
对于mouseenter来说,想象成是立体的空间,所以不会触发B区域的进入事件;
对于mouseout来说,因为有冒泡机制,所以触发A区域的离开事件同时,也会触发B、C区域的离开事件,由内向外依次执行;
对于mouseover来说,想象成是一个平面,所以会触发B区域的进入事件,同时由于冒泡机制也会触发C区域的进入事件,由内向外依次执行;
监听鼠标从A区域(子元素)移动到B区域(A的父元素、C的子元素)的捕获阶段
对于mouseleave来说,因为有捕获机制,所以触发A区域的离开事件同时,也会触发B、C区域的离开事件;由外向内依次执行;
对于mouseenter来说,想象成是立体的空间,所以不会触发B区域的进入事件;
对于mouseout来说,因为有捕获机制,所以触发A区域的离开事件同时,也会触发B、C区域的离开事件;由外向内依次执行;
对于mouseover来说,想象成是一个平面,所以会触发B区域的进入事件,同时由于捕获机制也会触发C区域的进入事件,由外向内依次执行;
以下是我作各种尝试时的代码,方便大家做测试
<!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> <style> #box1{ width: 400px; padding: 100px; padding-bottom: 0; background-color: yellow; /* 解决margin的传递问题,也是为了验证鼠标移动到margin部分也算是离开 */ border: 1px solid #000; } #box2{ width: 200px; height: 200px; padding: 100px; background-color: yellowgreen; margin-bottom: 100px; } #box3{ width: 200px; height: 200px; background-color: aqua; } </style> </head> <body> <div id="box1"> <div id="box2"> <div id="box3"> </div> </div> </div> <script> var box1 = document.getElementById('box1'); var box2 = document.getElementById('box2'); var box3 = document.getElementById('box3'); // box1.addEventListener('mouseleave',function(){ // console.log('移出1'); // },true) // box2.addEventListener('mouseleave',function(){ // console.log('移出2'); // },true) // box3.addEventListener('mouseleave',function(){ // console.log('移出3'); // },true) // box1.addEventListener('mouseleave',function(){ // console.log('移出1'); // },false) // box2.addEventListener('mouseleave',function(){ // console.log('移出2'); // },false) // box3.addEventListener('mouseleave',function(){ // console.log('移出3'); // },false) // box1.addEventListener('mouseout',function(){ // console.log('移出1'); // },true) // box2.addEventListener('mouseout',function(){ // console.log('移出2'); // },true) // box3.addEventListener('mouseout',function(){ // console.log('移出3'); // },true) // box1.addEventListener('mouseout',function(){ // console.log('移出1'); // },false) // box2.addEventListener('mouseout',function(){ // console.log('移出2'); // },false) // box3.addEventListener('mouseout',function(){ // console.log('移出3'); // },false) // box1.addEventListener('mouseover',function(){ // console.log('移入1'); // },true) // box2.addEventListener('mouseover',function(){ // console.log('移入2'); // },true) // box3.addEventListener('mouseover',function(){ // console.log('移入3'); // },true) // box1.addEventListener('mouseenter',function(){ // console.log('移入1'); // },true) // box2.addEventListener('mouseenter',function(){ // console.log('移入2'); // },true) // box3.addEventListener('mouseenter',function(){ // console.log('移入3'); // },true) </script> </body> </html>
写在最后,起因是当我在尝试事件委托时,我发现如果我去监听mouseenter的捕获阶段,也能实现委托,然后就去做各种尝试,继而跳出了更多的问题,最后总结出了这样一套原理。有了这些原理之后,对于事件委托的理解也就更深刻了,也知道了为什么mouseenter的捕获阶段能实现事件委托。
希望对大家有帮助!
正在回答
同学你好,按照同学的思路去理解,老师个人是认同的。很棒!继续努力,祝学习愉快!
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星