SD9015: 各浏览器对于 DOM 对象的鼠标滚轮事件事件存在差异

作者:武利剑

标准参考

无。

问题描述

元素的 mousewheel 事件在各浏览器中存在差异。

造成的影响

此问题可能会使预想的动作无法执行。

受影响的浏览器

所有浏览器  

问题分析

1. onmousewheel 事件

鼠标滚轮事件是 onmousewheel,它适合所有的 HTML element,也就是所有 HTML 对象和 XHTML 对象

onmousewheel 事件存在于 HTML5 规范草案中,现行 DOM 规范中没有这个消息,详细信息请参考:6.1.6.2 Event handlers on elements

IE 自从 IE6 版本就引入了 onmousewheel,后续版本也都提供了很好的支持。见 MSDN:onmousewheel Event

Chrome Safari Opera 也都支持 onmousewheel 事件。

Element 的onmousewheel事件

分析以下代码:

<script type="text/javascript">
    window.onload = function() {
        document.getElementById("one").onmousewheel = function() {
            document.getElementById("info").innerHTML="It worked";
        }
    }
</script>
<div id="one" style="width:100px; height:100px; overflow:auto; background-color:gold;">
</div>
<div id="info"></div>

上面代码中,给 one 绑定了 onmousewheel 事件。如果 onmousewheel 生效,在 one 的下方会生成一行字:"It worked"。

此测试用例不涉及事件绑定差异,因此采用元素后直接绑定的方式。

这段代码在不同的浏览器环境中表现如下 (在鼠标光标定位到金色区域时滚动鼠标后的截图):

IE Opera Safari Chrome Firefox

可见,在 Firefox 中没有任何的反应,也就是说,Firefox 不支持 onmousewheel 事件。

window和document的onmousewheel事件

分析以下代码:

<script type="text/javascript">
    window.onload = function() {
        document.onmousewheel = function() {
            document.getElementById("info").innerHTML = "It worked";
        }
    }
</script>
<div id="info"></div>

当鼠标在浏览器中滚动时,IE6 IE7 IE8 Safari Chrome Opera 都有“It worked”字样输出。

修改 documentwindow 后,只有 Safari Chrome Opera 输出了“It worked”。

浏览器对 onmousewheel 事件的支持情况汇总,如下表:

元素类型 IE6 IE7 IE8 Firefox Safari Opera Chrome
普通元素 Y Y Y N Y Y Y
window N N N N Y Y Y
document Y Y Y N Y Y Y

2. Firefox 中独有的 DOMMouseScroll 事件

Firefox 浏览器与其他浏览器不同,有自己独有的鼠标滚轮事件。

mozilla开发者中心(mozilla developer center)的页面上提供了一些 Gecko 相关的事件,其中的 DOMMouseScroll 事件就是用来捕捉鼠标滚轮事件的。

分析以下代码:

<script type="text/javascript">
    window.onload = function() {
        document.getElementById("one").addEventListener('DOMMouseScroll', function() {
            document.getElementById("info").innerHTML = "It worked";
        }, false);
    }
</script>
<div id="one" style="width:100px; height:100px; overflow:auto; background-color:gold;">
</div>
<div id="info"></div>

以上代码,在鼠标滚轮滚动时,只有在 Firefox 中才会出现“It worked”。


3. detail 与 wheelDelta

可以用 detail 或 wheelDelta 来判断鼠标滚动的方向是向上还是向下。

detail 是 Firefox 事件对象中的属性,即 event.detail,它定义了鼠标滚轮移动的单位,detail 只取 ±3,其中正数值表示向下向右滚动,负数值则表示向上向左滚动。

wheelDelta 是其他浏览器鼠标滚动事件的属性,wheelDelta 只取 ±120,其中正数表示为向上滚动,负数表示向下滚动。参见 MSDN:wheelDelta Property

解决方案

利用浏览器类型判断,给各浏览器绑定各自支持的鼠标滚轮事件。如,res.html

<!DOCTYPE html>
<html>
<head>
<script>
  var ua = navigator.userAgent;
  Test = {
    version: (ua.match(/.+(?:rv|it|ra|ie|me)[\/: ]([\d.]+)/i)||[])[1],
    ie: /msie/i.test(ua) && !/opera/i.test(ua),
    op: /opera/i.test(ua),
    sa: /version.*safari/i.test(ua),
    ch: /chrome/.test(ua),
    ff: /gecko/i.test(ua) && !/webkit/i.test(ua),
    wk: /webkit/i.test(ua),
    mz: /mozilla/i.test(ua)&&!/(compatible|webkit)/i.test(ua)
  }
  
  function $(id) { return document.getElementById(id); }
  
  function addEvent(el, type, fn){
    (el.attachEvent) ? (el.attachEvent("on" + type, fn)) : (el.addEventListener(type, fn, false));
  };

  function fixMouseWheel(elem, fn) {
    var mousewheel = Test.ff ? "DOMMouseScroll" : "mousewheel";
    (elem == null || elem == window ) && (elem = document);
    return {
      type: mousewheel,
      elem: elem,
      fn: function(e){
        var delta = 0;
        e = e || window.event;
        if (e.wheelDelta) {
          delta = event.wheelDelta / 120;
          if ( Test.op && Test.version < 10 ) delta = -delta;
        } else if (e.detail) {
          delta = -e.detail / 3;
        }
        e.delta = Math.round(delta);
        fn.call(elem, e);
      }
    }
  }
  var a = fixMouseWheel($("d"), function (e) {
    $("e").innerHTML = e.delta;
  });
  addEvent(a.elem, a.type, a.fn);
</script>
</head>
<body>
  <div id="d" style="width:200px; height:200px; border:1px solid black; overflow:scroll; position:relative;">
    <div id="e" style="position:absolute; top:0; left:0;"></div>
  </div>
</body>
</html>

参见

知识库

相关问题

测试环境

操作系统版本: Windows 7 Ultimate build 7600
浏览器版本: IE6
IE7
IE8
Firefox 3.6.4
Chrome 6.0.437.3 dev
Safari 5.0
Opera 10.60
  normal_element_onmousewheel_event.html
document_mousewheel.html
window_mousewheel.html
res.html
本文更新时间: 2010-08-02

关键字

onmousewheel DOMMouseScroll document window wheel mouse 滚轮