鼠标事件延时切换插件
鼠标事件延时切换插件
发布时间:2016-12-30 来源:查字典编辑
摘要:原理很简单:onmouseover、onmouseout执行业务代码时使用setTimeout进行延时,第二次触发的时候先清除掉前面的set...

原理很简单:

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插件版

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新Javascript教程学习
热门Javascript教程学习
编程开发子分类