鼠标经过子元素触发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 相关文章推荐
Firebug入门指南(Firefox浏览器)
Aug 21 Javascript
javascript使用prototype完成单继承
Dec 24 Javascript
js实现网页多级级联菜单代码
Aug 20 Javascript
JS实现带鼠标效果的头像及文章列表代码
Sep 27 Javascript
js实现图片切换(动画版)
Dec 25 Javascript
jQuery EasyUI Draggable拖动组件
Mar 01 Javascript
第一个Vue插件从封装到发布
Nov 22 Javascript
监听angularJs列表数据是否渲染完毕的方法示例
Nov 07 Javascript
微信小程序使用npm包的方法步骤
Aug 13 Javascript
微信小程序中的上拉、下拉菜单功能
Mar 13 Javascript
Vue + Scss 动态切换主题颜色实现换肤的示例代码
Apr 27 Javascript
微信小程序之滑动页面隐藏和显示组件功能的实现代码
Jun 19 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
解析VS2010利用VS.PHP插件调试PHP的方法
2013/07/19 PHP
PHP资源管理框架Assetic简介
2014/06/12 PHP
使用XHProf查找PHP性能瓶颈的实例
2017/12/13 PHP
PHP定义字符串的四种方式详解
2018/02/06 PHP
select、radio表单回显功能实现避免使用jquery载入赋值
2013/06/08 Javascript
js 实现浏览历史记录示例
2014/04/20 Javascript
JS获取图片lowsrc属性的方法
2015/04/01 Javascript
基于JQuery打造无缝滚动新闻步骤详解
2016/03/31 Javascript
使用nodejs中httpProxy代理时候出现404异常的解决方法
2016/08/15 NodeJs
JavaScript lodash常见用法系列小结
2016/08/24 Javascript
AngularJs $parse、$eval和$observe、$watch详解
2016/09/21 Javascript
flexslider.js实现移动端轮播
2017/02/05 Javascript
JavaScript Base64 作为文件上传的实例代码解析
2017/02/14 Javascript
微信小程序商城项目之购物数量加减(3)
2017/04/17 Javascript
VsCode新建VueJs项目的详细步骤
2017/09/23 Javascript
Vue2.0子同级组件之间数据交互方法
2018/02/28 Javascript
详解angular分页插件tm.pagination二次触发问题解决方案
2018/07/20 Javascript
Jquery+AJAX实现无刷新上传并重命名文件操作示例【PHP后台接收】
2020/05/29 jQuery
[01:58]DOTA2上海特级锦标赛现场采访:RTZ这个ID到底好不好
2016/03/25 DOTA
[46:44]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD BO3 第二场 3月7日
2021/03/11 DOTA
[52:02]DOTA2-DPC中国联赛 正赛 Phoenix vs Dragon BO3 第二场 2月26日
2021/03/11 DOTA
Python实现的文本简单可逆加密算法示例
2017/05/18 Python
python实现zabbix发送短信脚本
2018/09/17 Python
通过 Python 和 OpenCV 实现目标数量监控
2020/01/05 Python
浅谈Pytorch中的自动求导函数backward()所需参数的含义
2020/02/29 Python
CSS3 box-shadow属性实例详解
2020/06/19 HTML / CSS
英国乡村时尚和宠物用品专家:Pet & Country
2018/07/02 全球购物
美国时尚假发购物网站:Wigsbuy
2019/04/06 全球购物
"序列点" 是什么
2016/07/29 面试题
网络编程中设计并发服务器,使用多进程与多线程,请问有什么区别?
2016/03/27 面试题
大唐面试试题(CPU,UNIX等等)
2012/01/11 面试题
实习生个人总结范文
2015/02/28 职场文书
2015年八一建军节活动总结
2015/03/20 职场文书
详解nginx安装过程并代理下载服务器文件
2022/02/12 Servers
数据分析数据库ClickHouse在大数据领域应用实践
2022/04/03 MySQL
电脑只能进入安全模式无法正常启动的解决办法
2022/04/08 数码科技