Javascript 跨浏览器标准化鼠标滚轮速度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5527601/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:39:21  来源:igfitidea点击:

Normalizing mousewheel speed across browsers

javascriptmousewheel

提问by Phrogz

For a different questionI composed this answer, including this sample code.

对于一个不同的问题,我编写了这个答案,包括这个示例代码

In that code I use the mouse wheel to zoom in/out of an HTML5 Canvas. I found some code that normalizes speed differences between Chrome and Firefox. However, the zoom handling in Safari is much, much faster than in either of those.

在该代码中,我使用鼠标滚轮放大/缩小 HTML5 Canvas。我发现一些代码可以规范 Chrome 和 Firefox 之间的速度差异。然而,Safari 中的缩放处理比其中任何一个都快得多。

Here's the code I currently have:

这是我目前拥有的代码:

var handleScroll = function(e){
  var delta = e.wheelDelta ? e.wheelDelta/40 : e.detail ? -e.detail/3 : 0;
  if (delta) ...
  return e.preventDefault() && false;
};
canvas.addEventListener('DOMMouseScroll',handleScroll,false); // For Firefox
canvas.addEventListener('mousewheel',handleScroll,false);     // Everyone else

What code can I use to get the same 'delta' value for the same amount of mouse wheel rolling across Chrome v10/11, Firefox v4, Safari v5, Opera v11 and IE9?

对于在 Chrome v10/11、Firefox v4、Safari v5、Opera v11 和 IE9 上滚动的相同数量的鼠标滚轮,我可以使用什么代码来获得相同的“delta”值?

This questionis related, but has no good answer.

这个问题是相关的,但没有很好的答案。

Edit: Further investigation shows that one scroll event 'up' is:

编辑:进一步调查表明,一个滚动事件“向上”是:

                  | evt.wheelDelta | evt.detail
------------------+----------------+------------
  Safari v5/Win7  |       120      |      0
  Safari v5/OS X  |       120      |      0
  Safari v7/OS X  |        12      |      0
 Chrome v11/Win7  |       120      |      0
 Chrome v37/Win7  |       120      |      0
 Chrome v11/OS X  |         3 (!)  |      0      (possibly wrong)
 Chrome v37/OS X  |       120      |      0
        IE9/Win7  |       120      |  undefined
  Opera v11/OS X  |        40      |     -1
  Opera v24/OS X  |       120      |      0
  Opera v11/Win7  |       120      |     -3
 Firefox v4/Win7  |    undefined   |     -3
 Firefox v4/OS X  |    undefined   |     -1
Firefox v30/OS X  |    undefined   |     -1

Further, using the MacBook trackpad on OS X gives different results even when moving slowly:

此外,即使在缓慢移动时,在 OS X 上使用 MacBook 触控板也会产生不同的结果:

  • On Safari and Chrome, the wheelDeltais a value of 3 instead of 120 for mouse wheel.
  • On Firefox the detailis usually 2, sometimes 1, but when scrolling very slowly NO EVENT HANDLER FIRES AT ALL.
  • 在 Safari 和 Chrome 上,wheelDelta鼠标滚轮的值为 3 而不是 120。
  • 在 Firefoxdetail上通常是这样2,有时1,但是当滚动非常缓慢时,根本没有事件处理程序触发

So the question is:

所以问题是:

What is the best way to differentiate this behavior (ideally without any user agent or OS sniffing)?

区分这种行为的最佳方法是什么(理想情况下没有任何用户代理或操作系统嗅探)?

采纳答案by Phrogz

Edit September 2014

2014 年 9 月编辑

Given that:

鉴于:

  • Different versions of the same browser on OS X have yielded different values in the past, and may do so in the future, and that
  • Using the trackpad on OS X yields very similar effectsto using a mouse wheel, yet gives very different event values, and yet the device difference cannot be detected by JS
  • 同一浏览器在 OS X 上的不同版本过去产生了不同的价值,未来也可能如此,并且
  • 在 OS X 上使用触控板会产生与使用鼠标滚轮非常相似的效果,但会提供非常不同的事件,而且 JS 无法检测到设备差异

…I can only recommend using this simple, sign-based-counting code:

…我只能推荐使用这个简单的、基于符号的计数代码:

var handleScroll = function(evt){
  if (!evt) evt = event;
  var direction = (evt.detail<0 || evt.wheelDelta>0) ? 1 : -1;
  // Use the value as you will
};
someEl.addEventListener('DOMMouseScroll',handleScroll,false); // for Firefox
someEl.addEventListener('mousewheel',    handleScroll,false); // for everyone else


Original attempt to be correct follows.

最初的正确尝试如下。

Here is my first attempt at a script to normalize the values. It has two flaws on OS X: Firefox on OS X will produce values 1/3 what they should be, and Chrome on OS X will produce values 1/40 what they should be.

这是我第一次尝试使用脚本来规范化值。它在 OS X 上有两个缺陷:OS X 上的 Firefox 会产生应有值的 1/3,而 OS X 上的 Chrome 会产生应有值的 1/40。

// Returns +1 for a single wheel roll 'up', -1 for a single roll 'down'
var wheelDistance = function(evt){
  if (!evt) evt = event;
  var w=evt.wheelDelta, d=evt.detail;
  if (d){
    if (w) return w/d/40*d>0?1:-1; // Opera
    else return -d/3;              // Firefox;         TODO: do not /3 for OS X
  } else return w/120;             // IE/Safari/Chrome TODO: /3 for Chrome OS X
};

You can test out this code on your own browser here: http://phrogz.net/JS/wheeldelta.html

您可以在您自己的浏览器上测试此代码:http: //phrogz.net/JS/wheeldelta.html

Suggestions for detecting and improving the behavior on Firefox and Chrome on OS X are welcome.

欢迎提出检测和改进 OS X 上 Firefox 和 Chrome 行为的建议。

Edit: One suggestion from @Tom is to simply count each event call as a single move, using the sign of the distance to adjust it. This will not give great results under smooth/accelerated scrolling on OS X, nor handle perfectly cases when the mouse wheel is moved very fast (e.g. wheelDeltais 240), but these happen infrequently. This code is now the recommended technique shown at the top of this answer, for the reasons described there.

编辑:@Tom 的一个建议是简单地将每个事件调用计算为一次移动,使用距离的符号来调整它。这不会在 OS X 上的平滑/加速滚动下产生很好的结果,也不会完美地处理鼠标滚轮移动非常快(例如wheelDelta240)的情况,但这些情况很少发生。由于此处描述的原因,此代码现在是此答案顶部显示的推荐技术。

回答by smrtl

Here is my crazy attempt to produce a cross browser coherent and normalized delta ( -1 <= delta <= 1 ) :

这是我疯狂尝试生成跨浏览器一致且标准化的 delta ( -1 <= delta <= 1 ) :

var o = e.originalEvent,
    d = o.detail, w = o.wheelDelta,
    n = 225, n1 = n-1;

// Normalize delta
d = d ? w && (f = w/d) ? d/f : -d/1.35 : w/120;
// Quadratic scale if |d| > 1
d = d < 1 ? d < -1 ? (-Math.pow(d, 2) - n1) / n : d : (Math.pow(d, 2) + n1) / n;
// Delta *should* not be greater than 2...
e.delta = Math.min(Math.max(d / 2, -1), 1);

This is totally empirical but works quite good on Safari 6, FF 16, Opera 12 (OS X) and IE 7 on XP

这完全是经验性的,但在 XP 上的 Safari 6、FF 16、Opera 12 (OS X) 和 IE 7 上效果很好

回答by George

Our friends at Facebook put together a great solution to this problem.

我们在 Facebook 的朋友为这个问题提出了一个很好的解决方案。

I have tested on a data table that I'm building using React and it scrolls like butter!

我已经在我使用 React 构建的数据表上进行了测试,它像黄油一样滚动!

This solution works on a variety of browsers, on Windows/Mac, and both using trackpad/mouse.

此解决方案适用于 Windows/Mac 上的各种浏览器,并且都使用触控板/鼠标。

// Reasonable defaults
var PIXEL_STEP  = 10;
var LINE_HEIGHT = 40;
var PAGE_HEIGHT = 800;

function normalizeWheel(/*object*/ event) /*object*/ {
  var sX = 0, sY = 0,       // spinX, spinY
      pX = 0, pY = 0;       // pixelX, pixelY

  // Legacy
  if ('detail'      in event) { sY = event.detail; }
  if ('wheelDelta'  in event) { sY = -event.wheelDelta / 120; }
  if ('wheelDeltaY' in event) { sY = -event.wheelDeltaY / 120; }
  if ('wheelDeltaX' in event) { sX = -event.wheelDeltaX / 120; }

  // side scrolling on FF with DOMMouseScroll
  if ( 'axis' in event && event.axis === event.HORIZONTAL_AXIS ) {
    sX = sY;
    sY = 0;
  }

  pX = sX * PIXEL_STEP;
  pY = sY * PIXEL_STEP;

  if ('deltaY' in event) { pY = event.deltaY; }
  if ('deltaX' in event) { pX = event.deltaX; }

  if ((pX || pY) && event.deltaMode) {
    if (event.deltaMode == 1) {          // delta in LINE units
      pX *= LINE_HEIGHT;
      pY *= LINE_HEIGHT;
    } else {                             // delta in PAGE units
      pX *= PAGE_HEIGHT;
      pY *= PAGE_HEIGHT;
    }
  }

  // Fall-back if spin cannot be determined
  if (pX && !sX) { sX = (pX < 1) ? -1 : 1; }
  if (pY && !sY) { sY = (pY < 1) ? -1 : 1; }

  return { spinX  : sX,
           spinY  : sY,
           pixelX : pX,
           pixelY : pY };
}

The source code can be found here: https://github.com/facebook/fixed-data-table/blob/master/src/vendor_upstream/dom/normalizeWheel.js

源代码可以在这里找到:https: //github.com/facebook/fixed-data-table/blob/master/src/vendor_upstream/dom/normalizeWheel.js

回答by Sergio

I made a table with different values returned by different events/browsers, taking into account the DOM3wheelevent that some browsers already support (table under).

考虑到wheel某些浏览器已经支持的 DOM3事件(表下),我制作了一个由不同事件/浏览器返回的不同值的表格。

Based on that I made this function to normalize the speed:

基于此,我制作了此功能来规范速度:

http://jsfiddle.net/mfe8J/1/

http://jsfiddle.net/mfe8J/1/

function normalizeWheelSpeed(event) {
    var normalized;
    if (event.wheelDelta) {
        normalized = (event.wheelDelta % 120 - 0) == -0 ? event.wheelDelta / 120 : event.wheelDelta / 12;
    } else {
        var rawAmmount = event.deltaY ? event.deltaY : event.detail;
        normalized = -(rawAmmount % 3 ? rawAmmount * 10 : rawAmmount / 3);
    }
    return normalized;
}

Table for mousewheel, wheeland DOMMouseScrollevents:

mousewheel,wheelDOMMouseScroll事件的表:

| mousewheel        | Chrome (win) | Chrome (mac) | Firefox (win) | Firefox (mac) | Safari 7 (mac) | Opera 22 (mac) | Opera 22 (win) | IE11      | IE 9 & 10   | IE 7 & 8  |
|-------------------|--------------|--------------|---------------|---------------|----------------|----------------|----------------|-----------|-------------|-----------|
| event.detail      | 0            | 0            | -             | -             | 0              | 0              | 0              | 0         | 0           | undefined |
| event.wheelDelta  | 120          | 120          | -             | -             | 12             | 120            | 120            | 120       | 120         | 120       |
| event.wheelDeltaY | 120          | 120          | -             | -             | 12             | 120            | 120            | undefined | undefined   | undefined |
| event.wheelDeltaX | 0            | 0            | -             | -             | 0              | 0              | 0              | undefined | undefined   | undefined |
| event.delta       | undefined    | undefined    | -             | -             | undefined      | undefined      | undefined      | undefined | undefined   | undefined |
| event.deltaY      | -100         | -4           | -             | -             | undefined      | -4             | -100           | undefined | undefined   | undefined |
| event.deltaX      | 0            | 0            | -             | -             | undefined      | 0              | 0              | undefined | undefined   | undefined |
|                   |              |              |               |               |                |                |                |           |             |           |
| wheel             | Chrome (win) | Chrome (mac) | Firefox (win) | Firefox (mac) | Safari 7 (mac) | Opera 22 (mac) | Opera 22 (win) | IE11      | IE 10 & 9   | IE 7 & 8  |
| event.detail      | 0            | 0            | 0             | 0             | -              | 0              | 0              | 0         | 0           | -         |
| event.wheelDelta  | 120          | 120          | undefined     | undefined     | -              | 120            | 120            | undefined | undefined   | -         |
| event.wheelDeltaY | 120          | 120          | undefined     | undefined     | -              | 120            | 120            | undefined | undefined   | -         |
| event.wheelDeltaX | 0            | 0            | undefined     | undefined     | -              | 0              | 0              | undefined | undefined   | -         |
| event.delta       | undefined    | undefined    | undefined     | undefined     | -              | undefined      | undefined      | undefined | undefined   | -         |
| event.deltaY      | -100         | -4           | -3            | -0,1          | -              | -4             | -100           | -99,56    | -68,4 | -53 | -         |
| event.deltaX      | 0            | 0            | 0             | 0             | -              | 0              | 0              | 0         | 0           | -         |
|                   |              |              |               |               |                |                |                |           |             |           |
|                   |              |              |               |               |                |                |                |           |             |           |
| DOMMouseScroll    |              |              | Firefox (win) | Firefox (mac) |                |                |                |           |             |           |
| event.detail      |              |              | -3            | -1            |                |                |                |           |             |           |
| event.wheelDelta  |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.wheelDeltaY |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.wheelDeltaX |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.delta       |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.deltaY      |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.deltaX      |              |              | undefined     | undefined     |                |                |                |           |             |           |

回答by Marijn

Another more or less self-contained solution...

另一个或多或少独立的解决方案......

This doesn't take time between events into account though. Some browsers seem to always fire events with the same delta, and just fire them faster when scrolling quickly. Others do vary the deltas. One can imagine an adaptive normalizer that takes time into account, but that'd get somewhat involved and awkward to use.

但这并没有考虑事件之间的时间。一些浏览器似乎总是以相同的增量触发事件,并且在快速滚动时更快地触发它们。其他人确实改变了增量。可以想象一种考虑时间的自适应归一化器,但使用起来会有些复杂和笨拙。

Working available here: jsbin/iqafek/2

可在此处工作:jsbin/iqafek/2

var normalizeWheelDelta = function() {
  // Keep a distribution of observed values, and scale by the
  // 33rd percentile.
  var distribution = [], done = null, scale = 30;
  return function(n) {
    // Zeroes don't count.
    if (n == 0) return n;
    // After 500 samples, we stop sampling and keep current factor.
    if (done != null) return n * done;
    var abs = Math.abs(n);
    // Insert value (sorted in ascending order).
    outer: do { // Just used for break goto
      for (var i = 0; i < distribution.length; ++i) {
        if (abs <= distribution[i]) {
          distribution.splice(i, 0, abs);
          break outer;
        }
      }
      distribution.push(abs);
    } while (false);
    // Factor is scale divided by 33rd percentile.
    var factor = scale / distribution[Math.floor(distribution.length / 3)];
    if (distribution.length == 500) done = factor;
    return n * factor;
  };
}();

// Usual boilerplate scroll-wheel incompatibility plaster.

var div = document.getElementById("thing");
div.addEventListener("DOMMouseScroll", grabScroll, false);
div.addEventListener("mousewheel", grabScroll, false);

function grabScroll(e) {
  var dx = -(e.wheelDeltaX || 0), dy = -(e.wheelDeltaY || e.wheelDelta || 0);
  if (e.detail != null) {
    if (e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
    else if (e.axis == e.VERTICAL_AXIS) dy = e.detail;
  }
  if (dx) {
    var ndx = Math.round(normalizeWheelDelta(dx));
    if (!ndx) ndx = dx > 0 ? 1 : -1;
    div.scrollLeft += ndx;
  }
  if (dy) {
    var ndy = Math.round(normalizeWheelDelta(dy));
    if (!ndy) ndy = dy > 0 ? 1 : -1;
    div.scrollTop += ndy;
  }
  if (dx || dy) { e.preventDefault(); e.stopPropagation(); }
}

回答by robocat

For zoom support on touch devices, register for the gesturestart, gesturechange and gestureend events and use the event.scale property. You can see example codefor this.

对于触摸设备上的缩放支持,注册gesturestart、gesturechange 和gestureend 事件并使用event.scale 属性。您可以查看此示例代码

For Firefox 17 the onwheelevent is planned to be supported by desktop and mobile versions (as per MDN docs on onwheel). Also for Firefox maybe the Gecko specific MozMousePixelScrollevent is useful (although presumably this is now deprecated since the DOMMouseWheel event is now deprecated in Firefox).

对于 Firefox 17,该onwheel活动计划由桌面和移动版本支持(根据onwheel 上的 MDN 文档)。同样对于 Firefox,Gecko 特定MozMousePixelScroll事件可能很有用(尽管现在可能已经弃用了,因为 DOMMouseWheel 事件现在在 Firefox 中已弃用)。

For Windows, the driver itself seems to generate the WM_MOUSEWHEEL, WM_MOUSEHWHEEL events (and maybe the WM_GESTURE event for touchpad panning?). That would explain why Windows or the browser doesn't seem to normalise the mousewheel event values itself (and might mean you cannot write reliable code to normalise the values).

对于 Windows,驱动程序本身似乎会生成 WM_MOUSEWHEEL、WM_MOUSEHWHEEL 事件(也许还有用于触摸板平移的 WM_GESTURE 事件?)。这将解释为什么 Windows 或浏览器似乎没有规范化鼠标滚轮事件值本身(并且可能意味着您无法编写可靠的代码来规范化这些值)。

For onwheel(notonmousewheel) event support in Internet Explorerfor IE9 and IE10, you can also use the W3C standardonwheelevent. However one notch can be a value different from 120 (e.g. a single notch becomes 111 (instead of -120) on my mouse using this test page). I wrote another articlewith other details wheel events that might be relevant.

对于IE9 和 IE10 的Internet Explorer 中onwheel不是onmousewheel)事件支持,您还可以使用W3C 标准onwheel事件。然而,一个档位可以是不同于 120 的值(例如,使用此测试页在我的鼠标上,单个档位变为 111(而不是 -120))。我写了另一篇文章,其中包含可能相关的其他详细信息轮事件。

Basically in my own testing for wheel events (I am trying to normalise the values for scrolling), I have found that I get varying values for OS, browser vendor, browser version, event type, and device (Microsoft tiltwheel mouse, laptop touchpad gestures, laptop touchpad with scrollzone, Apple magic mouse, Apple mighty mouse scrollball, Mac touchpad, etc etc).

基本上在我自己对滚轮事件的测试中(我试图标准化滚动的值),我发现我得到了操作系统、浏览器供应商、浏览器版本、事件类型和设备(Microsoft 倾斜滚轮鼠标、笔记本电脑触摸板手势)的不同值、带滚动区的笔记本电脑触摸板、Apple 魔术鼠标、Apple 强大鼠标滚动球、Mac 触摸板等)。

And have to ignore a variety of side-effects from browser configuration (e.g. Firefox mousewheel.enable_pixel_scrolling, chrome --scroll-pixels=150), driver settings (e.g. Synaptics touchpad), and OS configuration (Windows mouse settings, OSX Mouse preferences, X.org button settings).

并且必须忽略浏览器配置(例如 Firefox mousewheel.enable_pixel_scrolling、chrome --scroll-pixels=150)、驱动程序设置(例如 Synaptics 触摸板)和操作系统配置(Windows 鼠标设置、OSX 鼠标首选项、 X.org 按钮设置)。

回答by Simone Gianni

This is a problem I've been fighting with for some hours today, and not for the first time :(

这是我今天一直在努力解决的一个问题,而不是第一次:(

I've been trying to sum up values over a "swipe" and see how different browsers report values, and they vary a lot, with Safari reporting order of magnitude bigger numbers on almost all platforms, Chrome reporting quite more (like 3 times more) than firefox, firefox being balanced on the long run but quite different among platforms on small movements (on Ubuntu gnome, nearly only +3 or -3, seems like it sums up smaller events and then send a big "+3")

我一直在尝试通过“滑动”来总结值,看看不同浏览器如何报告值,它们差异很大,几乎所有平台上 Safari 报告的数量级都更大,Chrome 报告的数量更多(比如 3 倍多) ) 与 firefox 相比,firefox 从长远来看是平衡的,但在小动作的平台之间有很大不同(在 Ubuntu gnome 上,几乎只有 +3 或 -3,似乎它总结了较小的事件,然后发送了一个大的“+3”)

The current solutions found right now are three :

目前找到的解决方案是三个:

  1. The already mentioned "use only the sign" which kills any kind of acceleration
  2. Sniff the browser up to minor version and platform, and adjust properly
  3. Qooxdoo recently implemented a self adapting algorithm, which basically tries to scale the delta based on minimum and maximum value received so far.
  1. 已经提到的“仅使用符号”会杀死任何类型的加速
  2. 嗅探浏览器到次要版本和平台,并适当调整
  3. Qooxdoo 最近实施了一种自适应算法,该算法基本上尝试根据迄今为止收到的最小值和最大值来缩放增量。

The idea in Qooxdoo is good, and works, and is the only solution I've currently found to be completely consistent cross browser.

Qooxdoo 中的想法很好,并且有效,并且是我目前发现的跨浏览器完全一致的唯一解决方案。

Unfortunately it tends to renormalize also the acceleration. If you try it (in their demos), and scroll up and down at maximum speed for a while, you'll notice that scrolling extremely fast or extremely slow basically produce nearly the same amount of movement. On the opposite if you reload the page and only swipe very slowly, you'll notice that it will scroll quite fast".

不幸的是,它也倾向于使加速度重新正常化。如果您尝试(在他们的演示中),并以最大速度上下滚动一段时间,您会注意到极快或极慢的滚动基本上会产生几乎相同的移动量。相反,如果您重新加载页面并且只非常缓慢地滑动,您会注意到它会滚动得非常快”。

This is frustrating for a Mac user (like me) used to give vigorous scroll swipes on the touchpad and expecting to get to the top or bottom of the scrolled thing.

对于习惯于在触摸板上剧烈滚动并期望到达滚动内容的顶部或底部的 Mac 用户(如我)来说,这令人沮丧。

Even more, since it scales down the mouse speed based on the maximum value obtained, the more your user tries to speed it up, the more it will slow down, while a "slow scrolling" user will experience quite fast speeds.

更重要的是,由于它根据获得的最大值缩小鼠标速度,因此您的用户尝试加快速度的次数越多,速度就越慢,而“慢速滚动”用户将体验到相当快的速度。

This makes this (otherwise brilliant) solution a slightly better implementation of solution 1.

这使得这个(否则很出色)解决方案成为解决方案 1 的稍微好一点的实现。

I ported the solution to the jquery mousewheel plugin : http://jsfiddle.net/SimoneGianni/pXzVv/

我将解决方案移植到 jquery mousewheel 插件:http: //jsfiddle.net/SimoneGianni/pXzVv/

If you play with it for a while, You'll see that you'll start getting quite homogeneous results, but you'll also notice that it tend to +1/-1 values quite fast.

如果您使用它一段时间,您会发现您将开始获得非常均匀的结果,但您还会注意到它趋向于 +1/-1 值的速度非常快。

I'm now working on enhancing it to detect peaks better, so that they don't send everything "out of scale". It would also be nice to also obtain a float value between 0 and 1 as the delta value, so that there is a coherent output.

我现在正在努力增强它以更好地检测峰值,这样它们就不会“超出规模”发送所有内容。获得一个介于 0 和 1 之间的浮点值作为 delta 值也很好,以便有一个连贯的输出。

回答by Marek

Simple and working solution:

简单而有效的解决方案:

private normalizeDelta(wheelEvent: WheelEvent):number {
    var delta = 0;
    var wheelDelta = wheelEvent.wheelDelta;
    var deltaY = wheelEvent.deltaY;
    // CHROME WIN/MAC | SAFARI 7 MAC | OPERA WIN/MAC | EDGE
    if (wheelDelta) {
        delta = -wheelDelta / 120; 
    }
    // FIREFOX WIN / MAC | IE
    if(deltaY) {
        deltaY > 0 ? delta = 1 : delta = -1;
    }
    return delta;
}

回答by ck_

There is definitely no simple way to normalize across all users in all OS in all browsers.

绝对没有简单的方法可以在所有浏览器中的所有操作系统中对所有用户进行标准化。

It gets worse than your listed variations - on my WindowsXP+Firefox3.6 setup my mousewheel does 6 per one-notch scroll - probably because somewhere I've forgotten I've accelerated the mouse wheel, either in the OS or somewhere in about:config

它比您列出的变体更糟糕 - 在我的 WindowsXP+Firefox3.6 设置中,我的鼠标滚轮每 1 个档位滚动 6 个 - 可能是因为我忘记了在某个地方我已经加速了鼠标滚轮,无论是在操作系统中还是在大约的某个地方:配置

However I am working on a similar problem (with a similar app btw, but non-canvas) and it occurs to me by just using the delta sign of +1 / -1 and measuring over timethe last time it fired, you'll have a rate of acceleration, ie. if someone scrolls oncevs several times in a few moments(which I would bet is how google maps does it).

但是,我正在处理类似的问题(顺便说一句,使用类似的应用程序,但不是画布),我只使用 +1 / -1 的 delta 符号并随着时间的推移测量它最后一次触发,你就会有一个加速度,即。如果有人滚动一次VS在几分钟几次(我敢打赌是谷歌如何映射做的话)。

The concept seems to work well in my tests, just make anything less than 100ms add to the acceleration.

这个概念在我的测试中似乎运行良好,只需将任何小于 100 毫秒的时间添加到加速中即可。

回答by Matthieu Chavigny

var onMouseWheel = function(e) {
    e = e.originalEvent;
    var delta = e.wheelDelta>0||e.detail<0?1:-1;
    alert(delta);
}
$("body").bind("mousewheel DOMMouseScroll", onMouseWheel);