将Edge / IE JavaScript WheelEvent增量转换为本机滚动量?

时间:2016-05-25 19:26:12

标签: javascript google-chrome internet-explorer microsoft-edge mousewheel

在Edge和Internet Explorer中,我注意到轮子事件的一个奇怪问题并不等于他们预期的滚动量。即使deltaMode值报告为DOM_DELTA_PIXEL0),deltaY中找到的像素数也会大于实际滚动的像素数。格。

以此代码为例:

<!DOCTYPE html>
<html>
    <head>
        <title>test</title>
        <style>
        #scroller {
            width: 200px;
            height: 200px;
            overflow: scroll;
        }
        </style>
    </head>
    <body>
        <div id="scroller">
            <p>test</p><p>test</p><p>test</p><p>test</p>
            <p>test</p><p>test</p><p>test</p><p>test</p>
            <p>test</p><p>test</p><p>test</p><p>test</p>
        </div>
        <script>
(function() {'use strict';
    var scroller = document.getElementById('scroller');
    scroller.addEventListener('wheel', function(e) {
        var scrollY = e.deltaY;
        console.log('scrollY:', scrollY);
        setTimeout(function() {
            console.log('scroller.scrollTop:', scroller.scrollTop);
        }, 250);
    });
})();
        </script>
    </body>
</html>

在控制台中,我看到这样的值:

scrollY: 101.8499984741211
scroller.scrollTop: 28

在Chrome等其他浏览器中,这些值匹配或至少非常接近。

因此实际滚动的数量与报告的数量不同。为什么会这样,我们能得到正确的价值吗?

1 个答案:

答案 0 :(得分:0)

值不同的原因是IE和Edge实际上根据滚动滚动区域的窗口占用量来缩小DOM像素。

这使得计算浏览器的正确缩放变得复杂,并且由于IE / Edge是唯一这样做的人,因此您将不得不使用某种形式的用户代理嗅探。

要获得正确的滚动量,您需要将deltaY乘以(scroller.clientHeight / window.innerHeight)(同样地deltaX)。

以下是具有这些调整的相同示例:

<!DOCTYPE html>
<html>
    <head>
        <title>test</title>
        <style>
        #scroller {
            width: 200px;
            height: 200px;
            overflow: scroll;
        }
        </style>
    </head>
    <body>
        <div id="scroller">
            <p>test</p><p>test</p><p>test</p><p>test</p>
            <p>test</p><p>test</p><p>test</p><p>test</p>
            <p>test</p><p>test</p><p>test</p><p>test</p>
        </div>
        <script>
(function() {
    'use strict';
    var scroller = document.getElementById('scroller');
    scroller.addEventListener('wheel', function(e) {
        var deltaY = e.deltaY;
        var scaleY = scroller.clientHeight / window.innerHeight;
        var scrollY = deltaY * scaleY;
        console.log('scrollY:', scrollY);
        setTimeout(function() {
            console.log('scroller.scrollTop:', scroller.scrollTop);
        }, 250);
    });
})();
        </script>
    </body>
</html>

在我的控制台中提供以下输出:

scrollY: 28.199999577518067
scroller.scrollTop: 28

请注意,scrollTop值没有浮点数,因此如果您希望值完全匹配,则可以Math.round