鼠标经过子元素触发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 相关文章推荐
一段利用WSH修改和查看IP配置的代码
May 11 Javascript
javascript TextArea动态显示剩余字符
Oct 22 Javascript
Javascript 构造函数 实例分析
Nov 26 Javascript
jquery 选择器引擎sizzle浅析
Feb 06 Javascript
使用js判断TextBox控件值改变然后出发事件
Mar 07 Javascript
jQuery的选择器中的通配符使用介绍
Mar 20 Javascript
JS生成不重复随机数组的函数代码
Jun 10 Javascript
jQuery提示效果代码分享
Nov 20 Javascript
javascript实现禁止右键和F12查看源代码
Dec 26 Javascript
jQuery模拟select实现下拉菜单功能
Jun 20 Javascript
jQuery+ajax实现动态添加表格tr td功能示例
Apr 23 jQuery
js中的this的指向问题详解
Aug 29 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
Zend Framework教程之Application用法实例详解
2016/03/14 PHP
深入理解PHP原理之执行周期分析
2016/06/01 PHP
PHP 返回数组后处理方法(开户成功后弹窗提示)
2017/07/03 PHP
PHP中strtr与str_replace函数运行性能简单测试示例
2019/06/22 PHP
Centos7安装swoole扩展操作示例
2020/03/26 PHP
Dojo 学习笔记入门篇 First Dojo Example
2009/11/15 Javascript
jquery 年会抽奖程序
2011/12/22 Javascript
JavaScript数组深拷贝和浅拷贝的两种方法
2014/04/16 Javascript
javascript中声明函数的方法及调用函数的返回值
2014/07/22 Javascript
jquery实现可旋转可拖拽的文字效果代码
2016/01/27 Javascript
JavaScript 字符串数字左补位,右补位,取固定长度,截位扩展函数代码
2017/03/25 Javascript
使用canvas及js简单生成验证码方法
2017/04/02 Javascript
seaJs使用心得之exports与module.exports的区别实例分析
2017/10/13 Javascript
webpack 3.X学习之多页面打包的方法
2018/09/04 Javascript
详细介绍解决vue和jsp结合的方法
2020/02/06 Javascript
js实现有趣的倒计时效果
2021/01/19 Javascript
跟老齐学Python之有点简约的元组
2014/09/24 Python
Python实现计算最小编辑距离
2016/03/17 Python
Windows上使用virtualenv搭建Python+Flask开发环境
2016/06/07 Python
Tensorflow使用tfrecord输入数据格式
2018/06/19 Python
Python判断一个list中是否包含另一个list全部元素的方法分析
2018/12/24 Python
详解Python 解压缩文件
2019/04/09 Python
利用Python的turtle库绘制玫瑰教程
2019/11/23 Python
django自定义非主键自增字段类型详解(auto increment field)
2020/03/30 Python
Python用来做Web开发的优势有哪些
2020/08/05 Python
通过Django Admin+HttpRunner1.5.6实现简易接口测试平台
2020/11/11 Python
SmartBuyGlasses比利时:购买品牌太阳镜和眼镜
2019/08/09 全球购物
联想印度官方网上商店:Lenovo India
2019/08/24 全球购物
结婚典礼证婚词
2014/01/08 职场文书
网吧消防安全制度
2014/01/28 职场文书
有关九一八事变的演讲稿
2014/09/14 职场文书
毕业横幅标语
2014/10/08 职场文书
街道党风廉政建设调研报告
2015/01/01 职场文书
2015年行风建设工作总结
2015/05/15 职场文书
工作时间证明
2015/06/15 职场文书
个人落户申请书怎么写?
2019/06/28 职场文书