jQuery中多个元素的Hover事件解决方案


Posted in Javascript onJune 12, 2014

1.需求简介

jQuery的hover事件只是针对单个HTML元素,例如:

$('#login').hover(fun2, fun2);

当鼠标进入#login元素时调用fun1函数,离开时则调用fun2函数,这种API已能够满足绝大部分需求。

不过,有些时候我们希望当鼠标进入两个或多个元素时触发fun1,离开他们时触发fun2,而在这些元素间移动鼠标并不触发任何事件。例如两个元素紧挨着的HTML元素,如下图:

jQuery中多个元素的Hover事件解决方案 

当鼠标进入二者的区域时触发fun1,离开时触发fun2。你也许会想到使用下面的方式

$('#trigger, #drop'),hover(fun1, fun2);

这种方式并不能满足我们的需求,因为从#trigger进入#drop时会触发fun2和fun1。要解决这个问题,一种比较简单的方式是更改HTML结构,实现方式如下:
<div id="container"> 
<div id="trigger"></div> 
<div id="drop"></div> 
</div> $('#container').hover(fun1, fun2);

这样通过在父元素上绑定hover事件来实现此功能。

2.示例研究

下图为常见的下拉菜单简化图,HTML结构如下:

jQuery中多个元素的Hover事件解决方案 

ul id="#nav"> 
<li></li> 
<li></li> 
<li id="droplist"> 
<span>下拉菜单</span> 
<ul> 
<li>下拉项1</li> 
<li>下拉项2</li> 
<li>下拉项3</li> 
<ul> 
</li> 
<li></li> 
</ul>

实现的JavaScrip程序也是非常简单
$('#droplist').hover(function(){ 
$(this).find('ul').show(); 
}, function(){ 
$(this).find('ul').hide(); 
});

这种实现方式逻辑清晰,但导致HTML嵌套层级过多,书写CSS时出现了许多不便。例如:
#nav li { font-size:14px; }

我们希望这段CSS为第一层li元素设置14像素字体,但是其也作用于了第二层元素,所以不得不使用下面的语句改写过来
#nav li li { font-size:12px; }

3.解决方案

更改HTML结构

<ul id="#nav"> 
<li></li> 
<li></li> 
<li id="trigger">下拉菜单</li> 
<li></li> 
</ul> 
<ul id="drop"> 
<li>下拉项1</li> 
<li>下拉项2</li> 
<li>下拉项3</li> 
<ul>

依次引入JS文件
<script type="text/javascript" src="js/jquery.js"></script> 
<script type="text/javascript" src="js/jquery.mixhover.js"></script>

控制代码
$.mixhover( 
'#trigger', 
'#drop', 
function(trg, drop){ 
#(drop).show(); 
}, 
function(trg, drop){ 
#(drop).hide(); 
} 
)

这样当鼠标进入#trigger时将#drop显示出来,鼠标从#trigger移如#drop时不会触发任何事件,实际上就是讲#trigger和#drop元素当做一个元素来处理。

jquery.mixhover.js程序如下

/** 
* Author: http://rainman.cnblogs.com/ 
* Date: 2014-06-06 
* Depend: jQuery 
*/ 
$.mixhover = function() { 
// 整理参数 $.mixhover($e1, $e2, handleIn, handleOut) 
var parms; 
var length = arguments.length; 
var handleIn = arguments[length - 2]; 
var handleOut = arguments[length - 1]; 
if ($.isFunction(handleIn) && $.isFunction(handleOut)) { 
parms = Array.prototype.slice.call(arguments, 0, length - 2); 
} else if ($.isFunction(handleOut)) { 
parms = Array.prototype.slice.call(arguments, 0, length - 1); 
handleIn = arguments[length - 1]; 
handleOut = null; 
} else { 
parms = arguments; 
handleIn = null; 
handleOut = null; 
} // 整理参数 使得elements依次对应 
var elems = []; 
for (var i = 0, len = parms.length; i < len; i++) { 
elems[i] = []; 
var p = parms[i]; 
if (p.constructor === String) { 
p = $(p); 
} 
if (p.constructor === $ || p.constructor === Array) { 
for (var j = 0, size = p.length; j < size; j++) { 
elems[i].push(p[j]); 
} 
} else { 
elems[i].push(p); 
} 
} 
// 绑定Hover事件 
for (var i = 0, len = elems[0].length; i < len; i++) { 
var arr = []; 
for (var j = 0, size = elems.length; j < size; j++) { 
arr.push(elems[j][i]); 
} 
$._mixhover(arr, handleIn, handleOut); 
} 
}; 
$._mixhover = function(elems, handleIn, handleOut) { 
var isIn = false, timer; 
$(elems).hover(function() { 
window.clearTimeout(timer); 
if (isIn === false) { 
handleIn && handleIn.apply(elems, elems); 
isIn = true; 
} 
}, 
function() { 
timer = window.setTimeout(function() { 
handleOut && handleOut.apply(elems, elems); 
isIn = false; 
}, 10); 
}); 
};
Javascript 相关文章推荐
javascript脚本调试方法小结
Nov 24 Javascript
javascript延时加载之defer测试
Dec 28 Javascript
Google Map V3 绑定气泡窗口(infowindow)Dom事件实现代码
Apr 26 Javascript
javascript中的throttle和debounce浅析
Jun 06 Javascript
JS获取网页图片name属性的方法
Apr 01 Javascript
JavaScript数据类型判定的总结笔记
Jul 31 Javascript
深入解析jQuery中Deferred的deferred.promise()方法
May 03 Javascript
详解从零搭建 vue2 vue-router2 webpack3 工程
Nov 22 Javascript
vue+axios+element ui 实现全局loading加载示例
Sep 11 Javascript
vue 父组件给子组件传值子组件给父组件传值的实例代码
Apr 15 Javascript
Vue组件模板的几种书写形式(3种)
Feb 19 Javascript
JS删除数组指定值常用方法详解
Jun 04 Javascript
js获取当前页面的url网址信息
Jun 12 #Javascript
jquery 3D 标签云示例代码
Jun 12 #Javascript
javascript面向对象特性代码实例
Jun 12 #Javascript
如何让浏览器支持jquery ajax load 前进、后退功能
Jun 12 #Javascript
js创建一个input数组并绑定click事件的方法
Jun 12 #Javascript
javascript实现阻止iOS APP中的链接打开Safari浏览器
Jun 12 #Javascript
jQuery实现复选框全选/取消全选/反选及获得选择的值
Jun 12 #Javascript
You might like
php empty() 检查一个变量是否为空
2011/11/10 PHP
php中如何使对象可以像数组一样进行foreach循环
2013/08/09 PHP
Laravel使用Queue队列的技巧汇总
2019/09/02 PHP
jquery获取下拉列表的值为null的解决方法
2011/03/18 Javascript
js实现div闪烁原理及实现代码
2014/06/24 Javascript
javascript比较两个日期的先后示例代码
2014/12/31 Javascript
jQuery的bind()方法使用详解
2015/07/15 Javascript
javascript入门之string对象【新手必看】
2016/11/22 Javascript
JQuery ZTree使用方法详解
2017/01/07 Javascript
详解前端构建工具gulpjs的使用介绍及技巧
2017/01/19 Javascript
解决使用Vue.js显示数据的时,页面闪现原始代码的问题
2018/02/11 Javascript
vue2中使用less简易教程
2018/03/27 Javascript
React+Webpack快速上手指南(小结)
2018/08/15 Javascript
js中的闭包实例展示
2018/11/01 Javascript
对于防止按钮重复点击的尝试详解
2019/04/22 Javascript
自定义Vue组件打包、发布到npm及使用教程
2019/05/22 Javascript
深入解析koa之中间件流程控制
2019/06/17 Javascript
Angular如何由模板生成DOM树的方法
2019/12/23 Javascript
vue项目使用$router.go(-1)返回时刷新原来的界面操作
2020/07/26 Javascript
python标准日志模块logging的使用方法
2013/11/01 Python
Python深入学习之内存管理
2014/08/31 Python
简介Python中用于处理字符串的center()方法
2015/05/18 Python
在Python的Django框架中编写编译函数
2015/07/20 Python
Python生成器以及应用实例解析
2018/02/08 Python
python实现多线程网页下载器
2018/04/15 Python
CSS3的新特性介绍
2008/10/31 HTML / CSS
俄罗斯厨房产品购物网站:COOK HOUSE
2021/03/15 全球购物
党员干部公开承诺书
2014/03/26 职场文书
小学庆六一活动总结
2014/08/28 职场文书
2014年合同管理工作总结
2014/12/02 职场文书
2014社区健康教育工作总结
2014/12/16 职场文书
安全员岗位职责
2015/02/10 职场文书
党支部半年考察意见
2015/06/01 职场文书
Nginx配置SSL证书出错解决方案
2021/03/31 Servers
详解Redis复制原理
2021/06/04 Redis
python中字符串String及其常见操作指南(方法、函数)
2022/04/06 Python