鼠标经过子元素触发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 各种浏览器下获得日期区别
Dec 22 Javascript
javascript通过navigator.userAgent识别各种浏览器
Oct 25 Javascript
JS方法调用括号的问题探讨
Jan 24 Javascript
node.js中的fs.mkdirSync方法使用说明
Dec 17 Javascript
JavaScript中的类数组对象介绍
Dec 30 Javascript
原生js实现移动开发轮播图、相册滑动特效
Apr 17 Javascript
jQuery操作Table技巧大汇总
Jan 23 Javascript
基于Javascript实现返回顶部按钮
Feb 29 Javascript
深入理解AngularJS中的ng-bind-html指令和$sce服务
Sep 08 Javascript
微信小程序 首页制作简单实例
Apr 07 Javascript
使用layui监听器监听select下拉框,事件绑定不成功的解决方法
Sep 28 Javascript
vue+Element-ui实现登录注册表单
Nov 17 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
destoon各类调用汇总
2014/06/20 PHP
php socket实现的聊天室代码分享
2014/08/16 PHP
yiic命令时提示“php.exe”不是内部或外部命令的解决方法
2014/12/18 PHP
wamp服务器访问php非常缓慢的解决过程
2015/07/01 PHP
PHP面向对象程序设计之类与反射API详解
2016/12/02 PHP
PHP从零开始打造自己的MVC框架之类的自动加载实现方法详解
2019/06/03 PHP
Yii2 queue的队列使用详解
2019/07/19 PHP
使用JQuery进行跨域请求
2010/01/25 Javascript
js中获取事件对象的方法小结
2011/03/13 Javascript
读jQuery之十 事件模块概述
2011/06/27 Javascript
JavaScript获取表单enctype属性的方法
2015/04/02 Javascript
每天一篇javascript学习小结(Array数组)
2015/11/11 Javascript
AngularJS入门教程一:路由用法初探
2017/05/27 Javascript
js中的闭包学习心得
2018/02/06 Javascript
详解node Async/Await 更好的异步编程解决方案
2018/05/10 Javascript
vue实现底部菜单功能
2018/07/24 Javascript
单页面vue引入百度统计的使用方法示例详解
2018/10/13 Javascript
生产制造追溯系统之再说条码打印
2019/06/03 Javascript
JavaScript实现Tab选项卡切换
2020/02/13 Javascript
JS 设计模式之:单例模式定义与实现方法浅析
2020/05/06 Javascript
Python中用sleep()方法操作时间的教程
2015/05/22 Python
python中文分词,使用结巴分词对python进行分词(实例讲解)
2017/11/14 Python
Pycharm+django2.2+python3.6+MySQL实现简单的考试报名系统
2019/09/05 Python
详解python 中in 的 用法
2019/12/12 Python
Python3.8.2安装包及安装教程图文详解(附安装包)
2020/11/28 Python
全球领先的中国制造商品在线批发平台:DHgate
2020/01/28 全球购物
监理员的岗位职责
2013/11/13 职场文书
中学生获奖感言
2014/02/04 职场文书
主管会计岗位责任制
2014/02/10 职场文书
小学生常见病防治方案
2014/06/06 职场文书
服务员态度差检讨书
2014/10/28 职场文书
自愿离婚协议书范本2016
2016/03/18 职场文书
高中班主任寄语
2019/06/21 职场文书
2019年员工晋升管理制度范本!
2019/07/08 职场文书
MySQL数据库索引的最左匹配原则
2021/11/20 MySQL
《游戏王:大师决斗》将推出新卡牌包4月4日上线
2022/03/31 其他游戏