DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> 鼠標事件延時切換插件
鼠標事件延時切換插件
編輯:關於JavaScript     
原理很簡單:
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的回調函數執行,這樣可以實現套嵌操作。

接口說明

方法 參數 作用 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插件版
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved