鼠标经过子元素触发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 相关文章推荐
(JS实现)MapBar中坐标的加密和解密的脚本
May 16 Javascript
JS OOP包机制,类创建的方法定义
Nov 02 Javascript
jquery中focus()函数实现当对象获得焦点后自动把光标移到内容最后
Sep 29 Javascript
jquery快捷动态绑定键盘事件的操作函数代码
Oct 17 Javascript
jQuery自动添加表单项的方法
Jul 13 Javascript
Angularjs中UI Router全攻略
Jan 29 Javascript
JS实现汉字与Unicode码相互转换的方法详解
Apr 28 Javascript
js实现音乐播放控制条
Sep 09 Javascript
JS简单实现数组去重的方法分析
Oct 14 Javascript
关于axios如何全局注册浅析
Jan 14 Javascript
在实例中重学JavaScript事件循环
Dec 03 Javascript
在vue中使用inheritAttrs实现组件的扩展性介绍
Dec 07 Vue.js
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
PHP 的 __FILE__ 常量
2007/01/15 PHP
tp5 实现列表数据根据状态排序
2019/10/18 PHP
[原创]js获取数组任意个不重复的随机数组元素
2010/03/15 Javascript
IE下window.onresize 多次调用与死循环bug处理方法介绍
2013/11/12 Javascript
Javascript获取数组中的最大值和最小值的方法汇总
2016/01/01 Javascript
AngularJs 60分钟入门基础教程
2016/04/03 Javascript
JS遍历页面所有对象属性及实现方法
2016/08/01 Javascript
使用jQuery5分钟快速搞定双色表格的简单实例
2016/08/08 Javascript
JavaScript日期对象(Date)基本用法示例
2017/01/18 Javascript
AngularJS基于factory创建自定义服务的方法详解
2017/05/25 Javascript
Vue实现active点击切换方法
2018/03/16 Javascript
Ajax请求时无法重定向的问题解决代码详解
2019/06/21 Javascript
wx-charts 微信小程序图表插件的具体使用
2019/08/18 Javascript
Vue v-for循环之@click点击事件获取元素示例
2019/11/09 Javascript
5分钟快速看懂ES6中的反射与代理
2019/12/19 Javascript
javascript设计模式 ? 抽象工厂模式原理与应用实例分析
2020/04/09 Javascript
[02:15]2014DOTA2国际邀请赛 赛后退役选手回顾
2014/08/01 DOTA
[02:01]大师之路——DOTA2完美大师赛11月论剑上海
2017/11/06 DOTA
Python实现全角半角字符互转的方法
2016/11/28 Python
python3.4下django集成使用xadmin后台的方法
2017/08/15 Python
python 接口返回的json字符串实例
2018/03/27 Python
Python单元测试实例详解
2018/05/25 Python
Python图像的增强处理操作示例【基于ImageEnhance类】
2019/01/03 Python
Python之修改图片像素值的方法
2019/07/03 Python
python爬虫 urllib模块发起post请求过程解析
2019/08/20 Python
Python各种扩展名区别点整理
2020/02/27 Python
python将unicode和str互相转化的实现
2020/05/11 Python
美国电视购物HSN官网:HSN
2016/09/07 全球购物
总监职责范文
2013/11/09 职场文书
职务聘任书范文
2014/03/29 职场文书
学习方法演讲稿
2014/05/10 职场文书
关于奉献的演讲稿
2014/05/21 职场文书
Python-OpenCV实现图像缺陷检测的实例
2021/06/11 Python
java设计模式--建造者模式详解
2021/07/21 Java/Android
JAVA API 实用类 String详解
2021/10/05 Java/Android
详细介绍MySQL中limit和offset的用法
2022/05/06 MySQL