其實在大多數瀏覽器(IE6, IE7, IE8, Opera 10+, Safari 5+)中,都提供了 “mousewheel” 事件。但杯具的是 Firefox 3.5+ 卻不支援此事件,不過慶幸 Firefox 3.5+ 中提供了另外一個等同的事件:”DOMMouseScroll” (事件和事件屬性的測試案例)。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Mousewheel Event in JavaScript</title> <style> body { padding:5px 10px; } .box { width:300px; height:150px; padding:10px; border:1px solid #999; background:#999; margin-bottom:20px; } .result strong { color:#f00; } </style> </head> <body> <h1>Mousewheel Event in JavaScript</h1> <ol> <li>IE6, IE7, IE8, Opera 10+, Safari 5+ support mousewheel.</li> <li>Firefox 3.5+ support DOMMouseScroll.</li> <li>IE6, IE7, IE8, Opera 10+, Safari 5+ support event.wheelDelta. </li> <li>Firefox 3.5+, Opera 10+ support event.detail.</li> <li>The event.wheelDelta value is a multiple of 120. </li> <li>The event.detail value is a multiple of 3.</li> </ol> <div id="J_Box01" class='box'>Mousewheel Event: mousewheel</div> <div id="J_Box02" class='box'>Mousewheel Event: DOMMouseScroll </div> <p id="J_Result" class="result"></p> <p>Related Articles: http://www.planabc.net/2010/08/12/mousewheel_event_in_javascript/</p> <script> (function(){ var addEvent = (function(){ if (window.addEventListener) { return function(el, sType, fn, capture) { el.addEventListener(sType, fn, (capture)); }; } else if (window.attachEvent) { return function(el, sType, fn, capture) { el.attachEvent("on" + sType, fn); }; } else { return function(){}; } })(), elBox01 = document.getElementById('J_Box01'), elBox02 = document.getElementById('J_Box02'), elResult = document.getElementById('J_Result'); // IE6/IE7/IE8/Opera 10+/Safari5+ addEvent(elBox01, 'mousewheel', function(event){ event = window.event || event ; elResult.innerHTML = 'This browser support <strong>mousewheel</strong> event! event.wheelDelt: <strong>' + (event.wheelDelta ? event.wheelDelta : '0') + '</strong>event.detail: <strong>' + (event.detail ? event.detail : '0') + '</strong>'; }, false); // Firefox 3.5+ addEvent(elBox02, 'DOMMouseScroll', function(event){ event = window.event || event ; elResult.innerHTML = 'This browser support <strong>DOMMouseScroll</strong> event! event.wheelDelt: <strong>' + (event.wheelDelta ? event.wheelDelta : '0') + '</strong>event.detail: <strong>' + (event.detail ? event.detail : '0') + '</strong>'; }, false); })(); </script> </body> </html>
[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]
OK,我們現在已經知道了不同瀏覽器之間實現的差別,相容代碼如下:
複製代碼 代碼如下:
var addEvent = (function(){
if (window.addEventListener) {
return function(el, sType, fn, capture) {
el.addEventListener(sType, fn, (capture));
};
} else if (window.attachEvent) {
return function(el, sType, fn, capture) {
el.attachEvent("on" + sType, fn);
};
} else {
return function(){};
}
})(),
// isFirefox 是虛擬碼,大家可以自行實現
mousewheel = isFirefox ? "DOMMouseScroll" : "mousewheel";
// object 也是虛擬碼,你需要註冊 Mousewheel 事件的元素
addEvent(object, mousewheel, function(event){
event = window.event || event;
// todo something
}, false);
我們再回到要實現的互動效果上,現在還有其他一些問題需要來解決:
1. 頁面字型到底是放大還是縮小呢? ==> 滑鼠滾輪是向上滾動還是向下滾動呢?
2. 頁面字型縮放的倍數到底是多少呢? ==> 滑鼠滾輪滾動的幅度大小是多少呢?
還好,我們可以通過 event 的某些屬性值得到這些資訊:
1. “mousewheel” 事件中的 “event.wheelDelta” 屬性值:返回的值,如果是正值說明滾輪是向上滾動,如果是負值說明滾輪是向下滾動;返回的值,均為 120 的倍數,即:幅度大小 = 返回的值 / 120。
2. “DOMMouseScroll” 事件中的 “event.detail” 屬性值:返回的值,如果是負值說明滾輪是向上滾動(與 “event.wheelDelta” 正好相反),如果是正值說明滾輪是向下滾動;返回的值,均為 3 的倍數,即:幅度大小 = 返回的值 / 3。
3. “mousewheel” 事件在 Opera 10+ 中卻是個特例,既有 “event.wheelDelta” 屬性,也有 “event.detail” 屬性。
註:上面第三點,在《The onmousewheel event of JavaScript》一文中有這樣一段批註:
複製代碼 代碼如下:
In Opera, “detail” returns the same value as it does in FF, so for the big O you should rely on “detail” instead of “wheelDelta”, which depending on the Opera version may return a different value than in IE's.
但經測試, Opera 9+ 和 Opera 10+ 中的 event.wheelDelta 屬性與其他瀏覽器中的表現完全一致,未發現異常與錯誤,從介面角度來說,代碼中應優先使用 “event.wheelDelta” 屬性。
此時代碼如下:
複製代碼 代碼如下:
var addEvent = (function(){
if (window.addEventListener) {
return function(el, sType, fn, capture) {
el.addEventListener(sType, fn, (capture));
};
} else if (window.attachEvent) {
return function(el, sType, fn, capture) {
el.attachEvent("on" + sType, fn);
};
} else {
return function(){};
}
})(),
stopEvent: function(event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
zoomIn = function(){},
zoomOut = function(){},
// isFirefox 是虛擬碼,大家可以自行實現
mousewheel = isFirefox ? "DOMMouseScroll" : "mousewheel";
// object 是虛擬碼,你需要註冊 Mousewheel 事件的元素
addEvent(object, mousewheel, function(event){
var delta = 0;
event = window.event || event;
stopEvent(event);
delta = event.wheelDelta ? (event.wheelDelta / 120) : (- event.detail / 3);
// zoomIn, zoomOut 是虛擬碼,需要實現的縮放事件
delta > 0 ? zoomIn(delta): zoomOut(Math.abs(delta));
} , false);