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 面向对象(一)(共有方法,私有方法,特权方法)
May 23 Javascript
node.js中的fs.rename方法使用说明
Dec 16 Javascript
Js可拖拽放大的层拖动特效实现方法
Feb 25 Javascript
jQuery+easyui中的combobox实现下拉框特效
Feb 27 Javascript
jquery小火箭返回顶部代码分享
Aug 19 Javascript
javascript实现禁止复制网页内容汇总
Dec 30 Javascript
AngularJS控制器继承自另一控制器
May 09 Javascript
纯js和css完成贪吃蛇小游戏demo
Sep 01 Javascript
JavaScript实现计算圆周率到小数点后100位的方法示例
May 08 Javascript
vue实现多条件和模糊搜索功能
May 28 Javascript
微信小程序tab切换可滑动切换导航栏跟随滚动实现代码
Sep 04 Javascript
解决vue字符串换行问题(绝对管用)
Aug 06 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中file_exists函数不支持中文名的解决方法
2014/07/26 PHP
php 获取xml接口数据的处理方法
2018/05/31 PHP
php unlink()函数使用教程
2018/07/12 PHP
php实现生成PDF文件的方法示例【基于FPDF类库】
2018/07/21 PHP
Nigma vs Liquid BO3 第一场2.13
2021/03/10 DOTA
javascript 特殊字符串
2009/02/25 Javascript
javascript操作Cookie(设置、读取、删除)方法详解
2015/03/18 Javascript
直接拿来用的15个jQuery代码片段
2015/09/23 Javascript
浅谈Javascript数组(推荐)
2016/05/17 Javascript
Nodejs进阶:express+session实现简易登录身份认证
2017/04/24 NodeJs
vue+webpack实现异步加载三种用法示例详解
2018/04/24 Javascript
Vue.js实现数据响应的方法
2018/08/13 Javascript
Vue-input框checkbox强制刷新问题
2019/04/18 Javascript
Vue.js+cube-ui(Scroll组件)实现类似头条效果的横向滚动导航条
2019/06/24 Javascript
Vue实现页面添加水印功能
2019/11/09 Javascript
js 计数排序的实现示例(升级版)
2020/01/12 Javascript
javascript实现贪吃蛇游戏(娱乐版)
2020/08/17 Javascript
快速解决vue2+vue-cli3项目ie兼容的问题
2020/11/17 Vue.js
Python性能优化技巧
2015/03/09 Python
Python中表达式x += y和x = x+y 的区别详解
2017/06/20 Python
python 中pyqt5 树节点点击实现多窗口切换问题
2019/07/04 Python
Django Python 获取请求头信息Content-Range的方法
2019/08/06 Python
Python实现图片裁剪的两种方式(Pillow和OpenCV)
2019/10/30 Python
python实现替换word中的关键文字(使用通配符)
2020/02/13 Python
Pyecharts地图显示不完成问题解决方案
2020/05/11 Python
详解Python利用configparser对配置文件进行读写操作
2020/11/03 Python
python压包的概念及实例详解
2021/02/17 Python
html5新增的定时器requestAnimationFrame实现进度条功能
2018/12/13 HTML / CSS
英国复古服装购物网站:Collectif
2019/10/30 全球购物
医药代表个人的求职信分享
2013/12/08 职场文书
物流合作计划书
2014/01/10 职场文书
财务科长个人对照检查材料
2014/09/18 职场文书
2015入党自荐书范文
2015/03/05 职场文书
停发工资证明范本
2015/06/12 职场文书
2016婚礼主持词开场白
2015/11/24 职场文书
Apache Kafka 分区重分配的实现原理解析
2022/07/15 Servers