鼠标经过子元素触发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 相关文章推荐
jQuery 操作XML入门
Dec 25 Javascript
js获取数组的最后一个元素
Apr 14 Javascript
javascript检查浏览器是否已经启用XX功能
Jul 10 Javascript
易被忽视的js事件问题总结
May 14 Javascript
jQuery simpleModal插件的使用介绍
Aug 30 Javascript
微信小程序实现image组件图片自适应宽度比例显示的方法
Jan 16 Javascript
vue动态设置img的src路径实例
Sep 18 Javascript
vue使用echarts图表的详细方法
Oct 22 Javascript
JavaScript设计模式之命令模式实例分析
Jan 16 Javascript
如何在Angular应用中创建包含组件方法示例
Mar 23 Javascript
小程序调用微信支付的方法
Sep 26 Javascript
JS如何监听div的resize事件详解
Dec 03 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
ThinkPHP水印功能实现修复PNG透明水印并增加JPEG图片质量可调整
2014/11/05 PHP
PHP高精确度运算BC函数库实例详解
2017/08/15 PHP
accesskey 提交
2006/06/26 Javascript
符合W3C网页标准的iframe标签的使用方法
2007/07/19 Javascript
jQuery生成asp.net服务器控件的代码
2010/02/04 Javascript
JQuery小知识
2010/10/15 Javascript
javascript动画对象支持加速、减速、缓入、缓出的实现代码
2012/09/30 Javascript
简单的两种Extjs formpanel加载数据的方式
2013/11/09 Javascript
js获取select标签选中值的两种方式
2014/01/09 Javascript
JavaScript获取元素尺寸和大小操作总结
2015/02/27 Javascript
简述AngularJS的控制器的使用
2015/06/16 Javascript
使用Node.js为其他程序编写扩展的基本方法
2015/06/23 Javascript
[原创]jQuery常用的4种加载方式分析
2016/07/25 Javascript
JS编写函数实现对身份证号码最后一位的验证功能
2016/12/29 Javascript
vue axios用法教程详解
2017/07/23 Javascript
不得不看之JavaScript构造函数及new运算符
2017/08/21 Javascript
element-ui 限制日期选择的方法(datepicker)
2018/05/16 Javascript
ElementUI多个子组件表单的校验管理实现
2019/11/07 Javascript
JavaScript实现烟花绽放动画效果
2020/08/04 Javascript
Django中使用group_by的方法
2015/05/26 Python
Python字符串的全排列算法实例详解
2019/01/07 Python
python计算阶乘和的方法(1!+2!+3!+...+n!)
2019/02/01 Python
Python3 max()函数基础用法
2019/02/19 Python
如何在django中添加日志功能
2020/02/06 Python
python通过对字典的排序,对json字段进行排序的实例
2020/02/27 Python
使用gunicorn部署django项目的问题
2020/12/30 Python
Sneaker Studio匈牙利:购买运动鞋
2018/03/26 全球购物
Bugatchi官方网站:男士服装在线
2019/04/10 全球购物
慕尼黑山地运动、户外服装和体育用品专家:Sporthaus Schuster
2019/08/27 全球购物
某/etc/fstab文件中的某行如下: /dev/had5 /mnt/dosdata msdos defaults,usrquota 1 2 请解释其含义
2013/04/11 面试题
this关键字的作用
2016/01/30 面试题
师范生实习个人的自我评价
2013/09/28 职场文书
课程设计心得体会
2013/12/28 职场文书
初中英语课后反思
2014/04/25 职场文书
竞选班干部演讲稿300字
2014/08/20 职场文书
三傻大闹宝莱坞观后感
2015/06/03 职场文书