鼠标经过子元素触发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选择器源码解读(八):addCombinator函数
Mar 31 Javascript
原生js的数组除重复简单实例
May 24 Javascript
如何利用模板将HTML从JavaScript中抽离
Oct 08 Javascript
jQuery插件ajaxFileUpload使用实例解析
Oct 19 Javascript
Angular2 PrimeNG分页模块学习
Jan 14 Javascript
JavaScript判断浏览器及其版本信息
Jan 20 Javascript
JavaScript引用类型Date常见用法实例分析
Aug 08 Javascript
Vue数据驱动表单渲染,轻松搞定form表单
Jul 19 Javascript
Vue实现页面添加水印功能
Nov 09 Javascript
vue.js 实现a标签href里添加参数
Nov 12 Javascript
手把手教您实现react异步加载高阶组件
Apr 07 Javascript
15分钟上手vue3.0(小结)
May 20 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
使用PHP实现下载CSS文件中的图片
2015/12/06 PHP
学习YUI.Ext 第六天--关于树TreePanel(Part 2异步获取节点)
2007/03/10 Javascript
JS URL传中文参数引发的乱码问题
2009/09/02 Javascript
为你的网站增加亮点的9款jQuery插件推荐
2011/05/03 Javascript
js预载入和JavaScript Image()对象使用介绍
2011/08/28 Javascript
js中有关IE版本检测
2012/01/04 Javascript
js获取多个tagname的节点数组
2013/09/22 Javascript
js中判断用户输入的值是否为空的简单实例
2013/12/23 Javascript
js控制分页打印、打印分页示例
2014/02/08 Javascript
Javascript同时声明一连串(多个)变量的方法
2017/01/23 Javascript
jQuery修改DOM结构_动力节点Java学院整理
2017/07/05 jQuery
JavaScript中的FileReader图片预览上传功能实现代码
2017/07/24 Javascript
使用Vue动态生成form表单的实例代码
2018/04/26 Javascript
NVM安装nodejs的方法实用步骤
2019/01/16 NodeJs
微信小程序前端自定义分享的实现方法
2019/06/13 Javascript
vue中使用element ui的弹窗与echarts之间的问题详解
2019/10/25 Javascript
Vue组件间数据传递的方式(3种)
2020/07/13 Javascript
基于Vue+Webpack拆分路由文件实现管理
2020/11/16 Javascript
[03:04]2018年国际邀请赛典藏宝瓶&莱恩声望物品展示 片尾有彩蛋
2018/06/04 DOTA
python 打印对象的所有属性值的方法
2016/09/11 Python
Python实现Youku视频批量下载功能
2017/03/14 Python
python同时遍历数组的索引和值的实例
2018/11/15 Python
Python with用法:自动关闭文件进程
2019/07/10 Python
python3使用GUI统计代码量
2019/09/18 Python
python实现将json多行数据传入到mysql中使用
2019/12/31 Python
Python3+selenium实现cookie免密登录的示例代码
2020/03/18 Python
浅谈Python中的模块
2020/06/10 Python
HTML5+Canvas+CSS3实现齐天大圣孙悟空腾云驾雾效果
2016/04/26 HTML / CSS
Oakley官网:运动太阳镜、雪镜和服装
2016/09/30 全球购物
斯凯奇澳大利亚官网:SKECHERS澳大利亚
2018/03/31 全球购物
Feelunique美国:欧洲大型的在线美妆零售电商
2018/11/04 全球购物
澳大利亚第一旅行车和房车配件店:Caravan RV Camping
2020/12/26 全球购物
遇到的Mysql的面试题
2014/06/29 面试题
党员干部群众路线个人整改措施
2014/09/18 职场文书
六查六看自查报告
2014/10/14 职场文书
httpclient调用远程接口的方法
2022/08/14 Java/Android