原理很简单: onmouseover、onmouseout执行业务代码时使用setTimeout进行延时,第二次触发的时候先清除掉前面的setTimeout。 原理 复制代码 代码如下: var timer; document.getElementById('test').onmouseover = function () { clearTimeout(timer); timer = setTimeout(function () { alert('over') }, 150); }; document.getElementById('test').onmouseout = function () { clearTimeout(timer); timer = setTimeout(function () { alert('out') }, 150); }; 上述代码可以看到,定时器返回值(唯一ID)由timer保存着,onmouseover与onmouserout都可以清除未执行的定时器,防止重复执行。这里timer让onmouseover与onmouserout有了一个“组”的概念,我们还可以让更多的元素能够访问到“组”,例如插入式的下拉菜单与tips等触发元素与弹出层都需要共用同一个timer,这样不会因为鼠标离开导致层被关闭(只要指针还在层上)。 封装事件 复制代码 代码如下: /*! * hoverDelay.js * http://www.planeArt.cn * Copyright 2011, TangBin * Dual licensed under the MIT or GPL Version 2 licenses. */ (function (pluginName) { var id = 0, data = {}, addEvent = function (elem, type, callback) { if (elem.addEventListener) { elem.addEventListener(type, callback, false); } else { elem.attachEvent('on' + type, function () {callback.call(elem)}); }; }; this[pluginName] = function (elem, over, out, group, speed) { id ++; if (arguments.length === 0) return id; if (typeof arguments[1] !== 'function') return clearTimeout(data[arguments[1]]); if (typeof elem === 'string') elem = document.getElementById(elem); group = group || elem[pluginName] || id; speed = speed || 150; elem[pluginName] = group; addEvent(elem, 'mouseover', function () { var elem = this, fn = function () {over.call(elem)}; clearTimeout(data[group]); data[group] = setTimeout(fn, speed); }); addEvent(elem, 'mouseout', function () { var elem = this, fn = function () {out.call(elem)}; clearTimeout(data[group]); data[group] = setTimeout(fn, speed); }); }; })('hoverDelay'); data负责保存着自定义的“组”,同一“组”下甚至可以暂停mouseout的回调函数执行,这样可以实现套嵌操作。
接口说明
#api table { width:99%; }
#api table th { color:#808080; font-weight:bold; text-shadow:1px 1px #FFF; }
#api td, #api th { padding:3px; }
#api td.time,#api th.time { color: #999; text-align: right; width: 110px; }
#api tr.odd td,#api tr.odd th { background-color:#F7F9FD; }
方法
参数
作用
hoverDelay (elem, over, out, group)
元素, 鼠标靠近时回调函数, 鼠标离开时回调函数, 设置延时分组名称[可选]
设置延时触发效果
hoverDelay (elem, group)
元素, 延时分组名称
停止鼠标离开执行的回调函数
hoverDelay ()
[无]
获取唯一延时分组名称2011-01-22更新 我注意到jQuery API中关于hover事件的说明: 会伴随着对鼠标是否仍然处在特定元素中的检测(例如,处在div中的图像),如果是,则会继续保持“悬停”状态,而不触发移出事件(修正了使用mouseout事件的一个常见错误)。 mouseout有BUG?这让我想起了我曾经工作中制作一个鼠标触发显示名片(类似腾讯微博的头像名片)经常被错误的执行了mouseout事件。于是我又查阅了jQuery的hover源码如何解决这个问题,发现它是使用“mouseenter”与“mouseleave”代替了“mouseover”与“mouseout”,“mouseenter”与“mouseleave”是IE(6、7、8)特有的的事件,标准浏览器并不支持,需要进行模拟,最终版本: 复制代码 代码如下: /*! * hoverDelay.js v1.1 * http://www.planeArt.cn * Copyright 2011, TangBin * Dual licensed under the MIT or GPL Version 2 licenses. */ (function (pluginName) { var id = 0, data = {}, addEvent = function (elem, type, callback) { if (elem.addEventListener) { if (type === 'mouseenter') { elem.addEventListener('mouseover', withinElement(callback), false); } else if (type === 'mouseleave') { elem.addEventListener('mouseout', withinElement(callback), false); } else { elem.addEventListener(type, callback, false); }; } else { elem.attachEvent('on' + type, function () {callback.call(elem, window.event)}); }; }, withinElement = function(callback) { return function (event) { var parent = event.relatedTarget; try { while (parent && parent !== this) parent = parent.parentNode; if (parent !== this) callback.apply(this, arguments); } catch(e) {}; }; }; this[pluginName] = function (elem, over, out, group, speed) { id ++; if (arguments.length === 0) return id; if (typeof arguments[1] !== 'function') return clearTimeout(data[arguments[1]]); if (typeof elem === 'string') elem = document.getElementById(elem); group = group || elem[pluginName] || id; speed = speed || 150; elem[pluginName] = group; addEvent(elem, 'mouseenter', function () { var elem = this, fn = function () {over.call(elem)}; clearTimeout(data[group]); data[group] = setTimeout(fn, speed); }); addEvent(elem, 'mouseleave', function () { var elem = this, fn = function () {out.call(elem)}; clearTimeout(data[group]); data[group] = setTimeout(fn, speed); }); }; })('hoverDelay'); 查看1.1版演示http://demo.jb51.net/js/2011/hover/index.htm 新窗口打开 下载 1、原生版1.1 2、jQuery插件版
推荐阅读
js中获取事件对象的方法小结
复制代码 代码如下: var evt = window.event || arguments[0]; 下面分三种添加事件的方式讨论,你也许会看到以前没有看到过的获取方式。 1,第一种添加事件的方式,直接在html的属性中写JS代码 复制代码 代码如下>>>详细阅读
本文标题:鼠标事件延时切换插件
地址:http://www.17bianji.com/kaifa2/JS/24834.html
1/2 1