找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1710|回复: 0

[教程] 浅谈 Mousewheel 事件

[复制链接]
发表于 2012-5-1 15:09:37 | 显示全部楼层 |阅读模式 来自 江苏省南京市

当需要制作转动鼠标滚轮放大页面字体这样的交互效果时,会用到Mousewheel 事件。其实在大多数浏览器(IE6, IE7, IE8, Opera 10+, Safari 5+)中,都提供了 “mousewheel” 事件。但杯具的是Firefox 3.5+ 却不支持此事件,不过庆幸 Firefox 3.5+ 中提供了另外一个等同的事件:”DOMMouseScroll” (事件和事件属性的测试案例)。

OK,我们现在已经知道了不同浏览器之间实现的差别,兼容代码如下:

  1. var addEvent = (function(){
  2.         if (window.addEventListener) {
  3.             return function(el, sType, fn, capture) {
  4.                 el.addEventListener(sType, fn, (capture));
  5.             };
  6.         } else if (window.attachEvent) {
  7.             return function(el, sType, fn, capture) {
  8.                 el.attachEvent("on" + sType, fn);
  9.             };
  10.         } else {
  11.             return function(){};
  12.         }
  13.     })(),
  14.     // isFirefox 是伪代码,大家可以自行实现
  15.     mousewheel = isFirefox ? "DOMMouseScroll" : "mousewheel";

  16. // object 也是伪代码,你需要注册 Mousewheel 事件的元素
  17. addEvent(object, mousewheel, function(event){
  18.     event = window.event || event;
  19.     // todo something
  20. }, false);
复制代码

我们再回到要实现的交互效果上,现在还有其他一些问题需要来解决:

  • 页面字体到底是放大还是缩小呢? ==> 鼠标滚轮是向上滚动还是向下滚动呢?
  • 页面字体缩放的倍数到底是多少呢? ==> 鼠标滚轮滚动的幅度大小是多少呢?

还好,我们可以通过 event 的某些属性值得到这些信息:

  • mousewheel” 事件中的 “event.wheelDelta” 属性值:返回的值,如果是正值说明滚轮是向上滚动,如果是负值说明滚轮是向下滚动;返回的值,均为 120 的倍数,即:幅度大小 = 返回的值 / 120。
  • DOMMouseScroll” 事件中的 “event.detail” 属性值:返回的值,如果是负值说明滚轮是向上滚动(与 “event.wheelDelta” 正好相反),如果是正值说明滚轮是向下滚动;返回的值,均为 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” 属性。

此时代码如下:

  1. var addEvent = (function(){
  2.         if (window.addEventListener) {
  3.             return function(el, sType, fn, capture) {
  4.                 el.addEventListener(sType, fn, (capture));
  5.             };
  6.         } else if (window.attachEvent) {
  7.             return function(el, sType, fn, capture) {
  8.                 el.attachEvent("on" + sType, fn);
  9.             };
  10.         } else {
  11.             return function(){};
  12.         }
  13.     })(),
  14.     stopEvent: function(event) {
  15.         if (event.stopPropagation) {
  16.             event.stopPropagation();
  17.         } else {
  18.             event.cancelBubble = true;
  19.         }

  20.         if (event.preventDefault) {
  21.             event.preventDefault();
  22.         } else {
  23.             event.returnValue = false;
  24.         }
  25.     },
  26.     zoomIn = function(){},
  27.     zoomOut = function(){},
  28.     // isFirefox 是伪代码,大家可以自行实现
  29.     mousewheel = isFirefox ? "DOMMouseScroll" : "mousewheel";

  30. // object 是伪代码,你需要注册 Mousewheel 事件的元素
  31. addEvent(object, mousewheel, function(event){
  32.     var delta = 0;
  33.     event = window.event || event;
  34.     stopEvent(event);

  35.     delta = event.wheelDelta ? (event.wheelDelta / 120) : (- event.detail / 3);
  36.     // zoomIn, zoomOut 是伪代码,需要实现的缩放事件
  37.     delta > 0 ? zoomIn(delta): zoomOut(Math.abs(delta));
  38. } , false);
复制代码

事件和事件属性的测试案例:http://www.planabc.net/demo/event/mousewheel.html

扩展阅读:《Mouse wheel programming in JavaScript


发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;

如何回报帮助你解决问题的坛友,好办法就是点击帖子下方的评分按钮给对方加【金币】不会扣除自己的积分,做一个热心并受欢迎的人!

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则 需要先绑定手机号

关闭

站长推荐上一条 /1 下一条

QQ|侵权投诉|广告报价|手机版|小黑屋|西部数码代理|飘仙建站论坛 ( 豫ICP备2022021143号-1 )

GMT+8, 2024-5-6 13:06 , Processed in 0.038509 second(s), 10 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表