关于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 星