现代浏览器中的鼠标滚轮事件

Posted

技术标签:

【中文标题】现代浏览器中的鼠标滚轮事件【英文标题】:Mousewheel event in modern browsers 【发布时间】:2013-02-02 07:07:54 【问题描述】:

我想为鼠标滚轮事件提供干净漂亮的 javascript,只支持最新版本的常见浏览器,没有旧版本的遗留代码,没有任何 JS 框架。

鼠标滚轮事件很好地解释了here。对于当前最新版本的浏览器,如何简化?

我无法访问所有浏览器来测试它,所以caniuse.com 对我有很大帮助。唉,那里没有提到鼠标滚轮。

根据 Derek 的评论,我编写了这个解决方案。对所有浏览器都有效吗?

someObject.addEventListener("onwheel" in document ? "wheel" : "mousewheel", function(e) 
  e.wheel = e.deltaY ? -e.deltaY : e.wheelDelta/40;
  // custom code
);

【问题讨论】:

Chrome 和 IE 支持MouseWheelEvent,而 Firefox 支持WheelEvent。如需跨浏览器收听,请参阅here。 补充到 Derek 的观点。在这些情况下,您应该真正评估浏览器的兼容性。您可以使用 Modernizr (modernizr.com) 做到这一点。它会让你的生活更轻松:) 现在,根据 MDN,所有现代桌面浏览器都支持 wheel 事件。 【参考方案1】:

干净简单:

window.addEventListener("wheel", event => console.info(event.deltaY));

浏览器可能会返回不同的增量值(例如,Chrome 返回+120(向上滚动)或-120(向下滚动)。标准化它的一个好技巧是提取其符号,有效地将其转换为@ 987654328@/-1:

window.addEventListener("wheel", event => 
    const delta = Math.sign(event.deltaY);
    console.info(delta);
);

参考:MDN。

【讨论】:

我宁愿保持 wheelDelta 的绝对值来检测滚动速度。是否有任何公式可以在浏览器中对此进行规范化? 很遗憾,如果要使用绝对值,则没有公式。您必须依赖某种表格,其中包含每个浏览器/操作系统组合的经验值。对于普通鼠标,wheelDelta 无论滚动多快都始终是固定的,所以可以按照我上面的建议进行操作。但是,例如,如果您想在触控板上捕捉灵敏度(我想这就是您要寻找的东西),那么您就是自己的了。让我们希望这个值在未来在浏览器中得到标准化。 这确实会在控制台中引发警报:[Violation] Added non-passive event listener to a scroll-blocking 'wheel' event. Consider marking event handler as 'passive' to make the page more responsive. Seechromestatus.com/feature/5745543795965952 有趣。我正在使用 Chrome 68,但没有看到此警报。 @DerkJanSpeelman 你确定你正在测试与上面完全相同的代码吗?我刚刚尝试了这两个版本(有和没有 delta 符号提取),但无法重现您所看到的。 我仍然无法在这里复制它。也许不同的操作系统?我正在 Ubuntu 18.04 上尝试它。另外,您是否同时运行任何额外的代码?无论如何,如果您不需要event.preventDefault(),将第三个参数 passive: true 传递给addEventListener() 的MDN mentions 可以解决问题。如果你这样做,它看起来像有not much you can do(检查人们在 cmets 中的抱怨)。【参考方案2】:

这里有一篇文章对此进行了描述,并举了一个例子:

http://www.sitepoint.com/html5-javascript-mouse-wheel/

相关代码,减去给出的调整图片大小的具体例子:

var myitem = document.getElementById("myItem");
if (myitem.addEventListener)

    // IE9, Chrome, Safari, Opera
    myitem.addEventListener("mousewheel", MouseWheelHandler, false);
    // Firefox
    myitem.addEventListener("DOMMouseScroll", MouseWheelHandler, false);

// IE 6/7/8
else

    myitem.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)));

    return false;

【讨论】:

优秀的答案。需要更多的关注。关于这个问题的许多不完整的答案, 这似乎是一个已弃用的事件,并且已从许多浏览器中删除。现在要使用的事件是“WheelEvent”(developer.mozilla.org/en-US/docs/Web/API/WheelEvent) 这对旧版浏览器支持很有用,特别是 IE 根本不支持 Math.sign,但支持 Math.max 和 Math.min。 caniuse.com/?search=Math.sign【参考方案3】:

这也适用于 Firefox、Chrome 和 Edge:

window.addEventListener("wheel", function(e) 
    var dir = Math.sign(e.deltaY);
    console.log(dir);
);

【讨论】:

以上是关于现代浏览器中的鼠标滚轮事件的主要内容,如果未能解决你的问题,请参考以下文章

jQuery中有鼠标滚轮事件么?

js中的鼠标滚轮事件

鼠标滚轮事件

各浏览器鼠标滚轮事件

JavaScript鼠标滚轮事件

监听鼠标滚轮事件