有时候遇到一个很宽的页面,想要用滚轮横向滚动,这时候一般的鼠标估计都不能做到吧?
说得有点抽象,Demo请点击:JS控制滚轮横向滚动演示
鼠标滚轮事件一直以来没有统一的事件。太混乱了,各种浏览器甚至操作系统都会产生差异。
简单点来看,分成两个时间段。
最初的时候,所有的浏览器,除了FireFox,都支持一个叫做MouseWheelEvent
的事件,甚至IE6都支持哦。
addEventListener使用mousewheel
即可,attachEvent则是onmousewheel
。
对于FireFox有一个类似的DOMMouseScroll
事件,addEventListener的时候监听addEventListener
。
然后,到了后来,其实也就是现在,有了一个新的、标准的滚轮事件,就叫WheelEvent
了。
得到了下列浏览器的支持:
Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
---|---|---|---|---|
31 | 17.0 (17.0) | 9.0 | Not supported | Not supported |
不过MDN说
This is really different event object from MouseWheelEvent.
具体怎么不一样,没有说,不过我不在意,不过估计主要是Delta增量的不一样。
不同浏览器不同操作系统下wheelDelta, wheelDeltaX and wheelDeltaY value的差异:MDN原文(En)
对我来说,Delta量多少都无所谓,我只需要得到正向还是反向滚轮就好了,正负判断即可,一次滚轮事件触发一次想要的效果。
来自于MDN的跨浏览器解决方案,它标准化了DeltaY和DeltaX:
// creates a global "addWheelListener" method // example: addWheelListener( elem, function( e ) { console.log( e.deltaY ); e.preventDefault(); } ); (function(window,document) {
var prefix = "", _addEventListener, onwheel, support;
// detect event model
if ( window.addEventListener ) {
_addEventListener = "addEventListener";
} else {
_addEventListener = "attachEvent";
prefix = "on";
}
// detect available wheel event
support = "onwheel" in document.createElement("div") ? "wheel" : // Modern browsers support "wheel"
document.onmousewheel !== undefined ? "mousewheel" : // Webkit and IE support at least "mousewheel"
"DOMMouseScroll"; // let's assume that remaining browsers are older Firefox
window.addWheelListener = function( elem, callback, useCapture ) {
_addWheelListener( elem, support, callback, useCapture );
// handle MozMousePixelScroll in older Firefox
if( support == "DOMMouseScroll" ) {
_addWheelListener( elem, "MozMousePixelScroll", callback, useCapture );
}
};
function _addWheelListener( elem, eventName, callback, useCapture ) {
elem[ _addEventListener ]( prefix + eventName, support == "wheel" ? callback : function( originalEvent ) {
!originalEvent && ( originalEvent = window.event );
// create a normalized event object
var event = {
// keep a ref to the original event object
originalEvent: originalEvent,
target: originalEvent.target || originalEvent.srcElement,
type: "wheel",
deltaMode: originalEvent.type == "MozMousePixelScroll" ? 0 : 1,
deltaX: 0,
delatZ: 0,
preventDefault: function() {
originalEvent.preventDefault ?
originalEvent.preventDefault() :
originalEvent.returnValue = false;
}
};
// calculate deltaY (and deltaX) according to the event
if ( support == "mousewheel" ) {
event.deltaY = - 1/40 * originalEvent.wheelDelta;
// Webkit also support wheelDeltaX
originalEvent.wheelDeltaX && ( event.deltaX = - 1/40 * originalEvent.wheelDeltaX );
} else {
event.deltaY = originalEvent.detail;
}
// it's time to fire the callback
return callback( event );
}, useCapture || false );
}
})(window,document);
除此之外,还会有jQuery的插件,可以像其它的普通事件一样使用,同样也标准化了deltaX
和deltaY
:
// using on
$('#my_elem').on('mousewheel', function(event) {
console.log(event.deltaX, event.deltaY, event.deltaFactor);
});
// using the event helper
$('#my_elem').mousewheel(function(event) {
console.log(event.deltaX, event.deltaY, event.deltaFactor);
});
插件地址:jQuery Mousewheel
个人倾向于使用插件,因为它考虑的情况更多一些,可能不同的操作系统下的都考虑好了,而且还有好心人维护。
不过可能不是每个人都需要用到那么多的功能,下面有一个简化版的鼠标滚轮事件,使用的是比较老的方法,没有使用最新的wheel事件,不过就目前来说适用。例子是在图像上滚滚轮缩放图像:
点击查看:滚轮缩放演示地址
HTML:
<img id="myimage" src="myimage.jpg" alt="my image" />
事件绑定:
var myimage = document.getElementById("myimage");
if (myimage.addEventListener) {
// IE9, Chrome, Safari, Opera
myimage.addEventListener("mousewheel", MouseWheelHandler, false);
// Firefox
myimage.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
}
// IE 6/7/8
else myimage.attachEvent("onmousewheel", MouseWheelHandler);
事件跨浏览器读取:
function MouseWheelHandler(e) {
// cross-browser wheel delta
var e = window.event || e; // old IE support
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail))); //判断滚轮方向
myimage.style.width = Math.max(50, Math.min(800, myimage.width + (30 * delta))) + "px";
return false;
}
参考资料:
https://developer.mozilla.org/en/docs/DOM/DOM_event_reference/mousewheel
https://developer.mozilla.org/en-US/docs/Web/API/MouseWheelEvent
https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent
https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/DOMMouseScroll