如何防止鼠标移出移入子元素触发mouseout和mouseover事件

<li v-for="item in liveData" :key="item.id" class="live-item" @mouseenter.prevent="onmouseoverItem" @mouseleave.prevent="onmouseoutItem">

我想实现的目标:当鼠标进入黑色框时,橙色框执行淡入动画;当黑色框范围移动的时候(即使经过粉色框,动画仍然不被触发);当鼠标移出的时候,橙色方块消失。

遇到的问题阐述:当鼠标移入黑色框的时候,橙色框执行淡入动画,但是当鼠标从黑色框经过粉色框的时候,橙色框就消失了,然后又执行一遍淡入动画。当鼠标从粉色框移出到黑色框的时候,橙色框的淡入动画又被执行。这不是我想要的。

初期代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html>
<head>
<script src= "jquery.js" ></script>
  <meta charset= "utf-8" >
  <title>mouseover mouseout</title>
  <style type= "text/css" media= "screen" >
    .parent{
  width:200px;
  height:200px;
  background:black;
}
.child{
  width:100px;
  height:100px;
  background:pink;
}
.a1{
  width:40px;
  height:40px;
  background:orange;
  display:none;
}
  </style>
</head>
<body>
<div class= "parent" >
  <div class= "child" ></div>
  <div class= "a1" ></div>
</div>
<script>
$( '.parent' ).on( 'mouseover' , function (e){
   $( '.a1' ).show(1000);
  });
  $( '.parent' ).on( 'mouseout' , function (e){
   $( '.a1' ).css( 'display' , 'none' );
  });
</script>
</body>
</html>

首先我们解释一下原因,为什么会出现这些问题。

当鼠标从黑色框移到粉色框的时候,此时黑色框的mouseout的被触发,又由于事件冒泡,黑色框的mouseover事件随即被触发,所以实际上,橙色框先消失,然后立即执行淡入动画。这也就是我们看到的过程。

当鼠标从粉色框移到黑色框的时候,此时黑色框的mouseout又被触发(因为不论鼠标穿过被选元素或其子元素,都触发 mouseover 事件),同时mouseover也被触发,所以又出现了再次执行淡入效果的过程。

方法一:用mouseleave/mouseout代替mouseover/mouseout【最佳方法】

先看一下mouseout&mouseover与mouseleave&mouseenter用法上的区别

mouseover与mouseenter

不论鼠标指针穿过被选元素或其子元素,都会触发 mouseover 事件。
只有在鼠标指针从元素外穿入被选元素(到元素内)时,才会触发 mouseenter 事件。

mouseout与mouseleave

不论鼠标指针离开被选元素还是任何子元素,都会触发 mouseout 事件。
只有在鼠标指针从元素内穿出被选元素(到元素外)时,才会触发 mouseleave 事件。

可以看一个简单的例子看看二者的区别

所以改进的代码可以为

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html>
<head>
<script src= "jquery.js" ></script>
  <meta charset= "utf-8" >
  <title>mouseover mouseout</title>
  <style type= "text/css" media= "screen" >
    .parent{
  width:200px;
  height:200px;
  background:black;
}
.child{
  width:100px;
  height:100px;
  background:pink;
}
.a1{
  width:40px;
  height:40px;
  background:orange;
  display:none;
}
  </style>
</head>
<body>
<div class= "parent" >
  <div class= "child" ></div>
  <div class= "a1" ></div>
</div>
<script>
$( '.parent' ).on( 'mouseenter' , function (e){
   $( '.a1' ).show(1000);
  });
  $( '.parent' ).on( 'mouseleave' , function (e){
   $( '.a1' ).css( 'display' , 'none' );
  });
</script>
</body>
</html>

方法二:利用e.stopPropagation()阻止事件进一步传播

e.stopPropagation()会终止事件在传播过程的捕获、目标处理或起泡阶段进一步传播。调用该方法后,该节点上处理该事件的处理程序将被调用,事件不再被分派到其他节点。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<!DOCTYPE html>
<html>
<head>
<script src= "jquery.js" ></script>
  <meta charset= "utf-8" >
  <title>mouseover mouseout</title>
  <style type= "text/css" media= "screen" >
    .parent{
  width:200px;
  height:200px;
  background:black;
}
.child{
  width:100px;
  height:100px;
  background:pink;
}
.a1{
  width:40px;
  height:40px;
  background:orange;
  display:none;
}
  </style>
</head>
<body>
<div class= "parent" >
  <div class= "child" ></div>
   <div class= "a1" ></div>
</div>
  <script>
  $( '.parent' ).on( 'mouseover' , function (e){
    $( '.a1' ).show(1000);
  });
  $( '.parent' ).on( 'mouseout' , function (e){
    $( '.a1' ).css( 'display' , 'none' );
  });
  $( '.child' ).on( 'mouseover' , function (e){
   e.stopPropagation();
   $( '.a1' ).css( 'display' , 'block' );
   //这是保证动画体的末状态不变
  });
  $( '.child' ).on( 'mouseout' , function (e){
   e.stopPropagation();
   //防止从粉色框移出到黑色框时再次触发其他事件
  })
  </script>
</body>
</html>

拓展思考:

1.如果子元素过多怎么办,难道每个都要去绑定e.stopPropagation()?

用jquery的一个选择器.children(),比如$('.parent').children()。获得匹配元素集合中每个元素的子元素。

以上所述就是本文的全部内容了,希望大家能够喜欢。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值