鼠标经过子元素触发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 相关文章推荐
Code:loadScript( )加载js的功能函数
Feb 02 Javascript
Javascript倒计时代码
Aug 12 Javascript
理运用命名空间让js不产生冲突避免全局变量的泛滥
Jun 15 Javascript
Bootstrap布局组件应用实例讲解
Feb 17 Javascript
angular route中使用resolve在uglify压缩后问题解决
Sep 21 Javascript
js中json处理总结之JSON.parse
Oct 14 Javascript
微信开发 使用picker封装省市区三级联动模板
Oct 28 Javascript
vue上传图片组件编写代码
Jul 26 Javascript
node的process以及child_process模块学习笔记
Mar 06 Javascript
vue router 源码概览案例分析
Oct 09 Javascript
vue项目中使用vue-i18n报错的解决方法
Jan 13 Javascript
ios中视频的最后一桢问题解决
May 14 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
windows中为php安装mongodb与memcache
2015/01/06 PHP
php去除html标记的原生函数详解
2015/01/27 PHP
PHP微信公众号开发之微信红包实现方法分析
2017/07/14 PHP
php微信公众号开发之现金红包
2018/04/16 PHP
PHP中十六进制颜色与RGB颜色值互转的方法
2019/03/18 PHP
PHP应用跨时区功能的实现方法
2019/03/21 PHP
JavaScript游戏之优化篇
2010/11/08 Javascript
js遍历td tr等html元素
2012/12/13 Javascript
jquery load事件(callback/data)使用方法及注意事项
2013/02/06 Javascript
详细分析使用AngularJS编程中提交表单的方式
2015/06/19 Javascript
纯JS实现本地图片预览的方法
2015/07/31 Javascript
每日十条JavaScript经验技巧(二)
2016/06/23 Javascript
VUE搭建手机商城心得和遇到的坑
2019/02/21 Javascript
vue全局自定义指令-元素拖拽的实现代码
2019/04/14 Javascript
vue路由缓存的几种实现方式小结
2020/02/02 Javascript
nodejs实现的http、https 请求封装操作示例
2020/02/06 NodeJs
JS实现多功能计算器
2020/10/28 Javascript
[44:01]2018DOTA2亚洲邀请赛3月30日 小组赛B组 EG VS paiN
2018/03/31 DOTA
从零学python系列之教你如何根据图片生成字符画
2014/05/23 Python
跟老齐学Python之网站的结构
2014/10/24 Python
Python调用命令行进度条的方法
2015/05/05 Python
使用rpclib进行Python网络编程时的注释问题
2015/05/06 Python
python删除本地夹里重复文件的方法
2020/11/19 Python
Python实现提取XML内容并保存到Excel中的方法
2018/09/01 Python
什么是Python中的顺序表
2020/06/02 Python
python设置中文界面实例方法
2020/10/27 Python
python math模块的基本使用教程
2021/01/16 Python
css3的@media属性实现页面响应式布局示例代码
2014/02/10 HTML / CSS
印尼购物网站:iLOTTE
2019/10/16 全球购物
意大利顶级奢侈品电商:LUISAVIAROMA(支持中文)
2020/05/26 全球购物
销售类个人求职信范文
2013/09/25 职场文书
《小池塘》教学反思
2014/02/28 职场文书
家长会标语
2014/06/24 职场文书
2014年党员评议表自我评价
2014/09/27 职场文书
公司离职证明标准样本
2014/10/05 职场文书
2014年工会工作总结
2014/11/12 职场文书