跨浏览器鼠标滚轮事件及测试用例
浏览器差异:
- Firefox的滚轮事件是DOMMouseScroll,其他浏览器使用的是mousewheel
- Firefox事件的event对象使用detail值表示滚轮方向,负3表示向上(前),正3表示向下(后)。其他浏览器使用wheelDelta值表示滚轮方向,正120表示向上(前),负120表示向下(后)。Opera 11.11即有detail值(同FF)也有wheelDelta值。
- 不要和正负3或正负120做等值比较来滚轮判断方向,应该和零比较。比如wheelDelta值大于0表示向上(前)。这么做的原因是有些用户的鼠标是基于厂家自己的驱动运行的,有更高级的灵敏度识别,在用户快速滚动滑轮的时候,event对象的detail或wheelDelta会出现其他值得情况。
- 经典得基本已成为废话,IE678使用attachEvent/detachEvent,其他浏览器使用addEventListener/removeEventListener。
封装后的代码,加入统一的方向标识和一些常用的功能:
- 为event对象加入wheel值表示滚轮方向,正1表示向上(前),负1表示向下(后)。
- 为event对象加入wheelDir值表示滚轮方向,up表示向上(前),down表示向下(后)。
- 纠正了IE678下事件函数内部的this值,指向绑定事件的DOM元素。
- 为IE678下事件函数传染event对象。
- 可以通过第三个参数决定是否阻止滚轮的默认行为,即触发整个网页的滚动事件。默认为true,阻止滚轮的默认行为。
- 同一个DOM元素可以绑定多个滚轮事件但不允许绑定重复的事件。
实现代码:
/* * mousewheel.js (c) Doomin|Joy-Studio * @example * mouseWheel.on(el, callback) * mouseWheel.on(el, callback, false) do NOT prevent default event * mouseWheel.un(el, callback) */ var mouseWheel = (function() { var doc = document, types = ['DOMMouseScroll', 'mousewheel'], fixedEvent = function(e) { e.wheel = (e.wheelDelta ? e.wheelDelta: -e.detail) > 0 ? 1 : -1; e.wheelDir = e.wheel > 0 ? 'up': 'down'; return e; }; //return the api method return { on: function(el, fn, preventDefault) { if (typeof preventDefault !== 'boolean') { preventDefault = true; } var fixedFn = function(e) { e = fixedEvent(e || window.event); if (preventDefault) { if (e.preventDefault) { e.preventDefault() } else { e.returnValue = false; } } fn.call(el, e); }, wheelHash = el.wheelHash; if (!wheelHash) { wheelHash = {}; wheelHash[fn] = fixedFn; el.wheelHash = wheelHash; } else { //ignore the repeat event if (wheelHash[fn]) return; wheelHash[fn] = fixedFn; } if (doc.addEventListener) { var i = types.length; while (i--) { el.addEventListener(types[i], fixedFn, false); } } else { el.attachEvent('onmousewheel', fixedFn); } }, un: function(el, fn) { if (!el.wheelHash) return; var wheelHash = el.wheelHash; if (doc.removeEventListener) { var i = types.length; while (i--) { el.removeEventListener(types[i], wheelHash[fn], false); } } else { el.detachEvent('onmousewheel', wheelHash[fn]); } delete wheelHash[fn]; } }; })();
如何使用:
//定义滚轮事件 var myWheel = function(e){ console.log(e.wheelDir); } //添加滚轮事件 mouseWheel.on(element, myWheel); //删除滚轮事件 mouseWheel.un(element, myWheel);
鼠标滚轮事件的几个经典应用:
- 地图,比如Google Map,百度地图。
- 表单Spinner控件。
- 自定义滚动条。
- 控制字体大小。
- 其他,有待同学们自己发现,创新和应用。
相关资源:http://www.adomas.org/javascript-mouse-wheel/
测试地址:http://www.joy-studio.com/demo/mousewheel/cross-browser-mousewheel-and-demo.html
原文地址:http://www.joy-studio.com/frontend-develop/cross-browser-mousewheel-and-demo.html