鼠标经过子元素触发mouseout,mouseover事件的解决方案


Posted in Javascript onJuly 26, 2015

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

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

初期代码:

<!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 事件。

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

所以改进的代码可以为

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

<!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()。获得匹配元素集合中每个元素的子元素。

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

Javascript 相关文章推荐
Prototype最新版(1.5 rc2)使用指南(1)
Jan 10 Javascript
javascript中字符串拼接详解
Sep 26 Javascript
使用jQuery.wechat构建微信WEB应用
Oct 09 Javascript
js实现上传图片预览的方法
Feb 09 Javascript
Javascript实现计算个人所得税
May 10 Javascript
JavaScript使用delete删除数组元素用法示例【数组长度不变】
Jan 17 Javascript
AngularJS使用拦截器实现的loading功能完整实例
May 17 Javascript
vue父组件通过props如何向子组件传递方法详解
Aug 16 Javascript
JS中touchstart事件与click事件冲突的解决方法
Mar 12 Javascript
Element输入框带历史查询记录的实现示例
Jan 15 Javascript
JavaScript设计模式之装饰者模式实例详解
Jan 17 Javascript
D3.js 实现带伸缩时间轴拓扑图的示例代码
Jan 20 Javascript
javascript中setTimeout使用指南
Jul 26 #Javascript
jquery不常用方法汇总
Jul 26 #Javascript
浅谈JavaScript中指针和地址
Jul 26 #Javascript
javascript的变量、传值、传址、参数之间关系
Jul 26 #Javascript
javascript实现动态导入js与css等静态资源文件的方法
Jul 25 #Javascript
javascript创建动态表单的方法
Jul 25 #Javascript
javascript文件加载管理简单实现方法
Jul 25 #Javascript
You might like
Terran兵种对照表
2020/03/14 星际争霸
Laravel 默认邮箱登录改成用户名登录的实现方法
2019/08/12 PHP
我见过最全的个人js加解密功能页面
2007/12/12 Javascript
潜说js对象和数组
2011/05/25 Javascript
javascript快速排序算法详解
2014/09/17 Javascript
javascript实现回到顶部特效
2015/05/06 Javascript
JS弹出新窗口被拦截的解决方法
2016/08/09 Javascript
原生js实现秒表计时器功能
2017/02/16 Javascript
深入探究AngularJs之$scope对象(作用域)
2017/07/20 Javascript
angularjs实现天气预报功能
2020/06/16 Javascript
详解vue 项目白屏解决方案
2018/10/31 Javascript
javascript将16进制的字符串转换为10进制整数hex
2020/03/05 Javascript
在Vue中使用Echarts实例图的方法实例
2020/10/10 Javascript
python中执行shell命令的几个方法小结
2014/09/18 Python
好用的Python编辑器WingIDE的使用经验总结
2016/08/31 Python
Python操作Access数据库基本步骤分析
2016/09/19 Python
python的paramiko模块实现远程控制和传输示例
2017/10/13 Python
通过Python 接口使用OpenCV的方法
2018/04/02 Python
学生信息管理系统Python面向对象版
2019/01/30 Python
基于django channel实现websocket的聊天室的方法示例
2019/04/11 Python
Python空间数据处理之GDAL读写遥感图像
2019/08/01 Python
使用Python实现文字转语音并生成wav文件的例子
2019/08/08 Python
Python多进程编程multiprocessing代码实例
2020/03/12 Python
Python中zip函数如何使用
2020/06/04 Python
html5绘制时钟动画
2014/12/15 HTML / CSS
Myprotein加拿大官网:欧洲第一的运动营养品牌
2018/01/06 全球购物
ZWILLING双立人英国网上商店:德国刀具锅具厨具品牌
2018/05/15 全球购物
英国书籍、CD、DVD和游戏的第一道德零售商:Awesome Books
2020/02/22 全球购物
Linux常见面试题
2013/03/18 面试题
升国旗仪式主持词
2014/03/19 职场文书
2015年度优秀员工获奖感言
2015/07/31 职场文书
小学班级口号大全
2015/12/25 职场文书
《金钱的魔力》教学反思
2016/02/20 职场文书
2016年五一国际劳动节活动总结
2016/04/06 职场文书
修改MySQL的数据库引擎为INNODB的方法
2021/05/26 MySQL
OpenCV-Python实现人脸美白算法的实例
2021/06/11 Python