首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在其他帖子中发现的滚动流畅代码中发现错误,但不知道如何修复

在其他帖子中发现的滚动流畅代码中发现错误,但不知道如何修复
EN

Stack Overflow用户
提问于 2019-08-06 04:29:42
回答 1查看 354关注 0票数 3

我在我的朋友谷歌上搜索了一些用于平滑滚动的代码,发现了这个:Smooth vertical scrolling on mouse wheel in vanilla javascript?

它工作得很好,但如果我滚动一次,然后尝试使用我的鼠标手动移动滚动条,它就坏了…

代码语言:javascript
复制
SmoothScroll(document, 120, 12);
        function SmoothScroll(target, speed, smooth) {
            if (target === document)
                target = (document.scrollingElement ||
                    document.documentElement ||
                    document.body.parentNode ||
                    document.body) // cross browser support for document scrolling

            var moving = false
            var pos = target.scrollTop
            var frame = target === document.body &&
                document.documentElement ?
                document.documentElement :
                target // safari is the new IE

            target.addEventListener('scroll', scrolled, {
                passive: false
            })
            target.addEventListener('mousewheel', scrolled, {
                passive: false
            })
            target.addEventListener('DOMMouseScroll', scrolled, {
                passive: false
            })

            function scrolled(e) {
                e.preventDefault(); // disable default scrolling

                var delta = normalizeWheelDelta(e)

                pos += -delta * speed
                pos = Math.max(0, Math.min(pos, target.scrollHeight - frame.clientHeight)) // limit scrolling
                if (!moving) update()
            }

            function normalizeWheelDelta(e) {
                if (e.detail) {
                    if (e.wheelDelta)
                        return e.wheelDelta / e.detail / 40 * (e.detail > 0 ? 1 : -1) // Opera
                    else
                        return -e.detail / 3 // Firefox
                } else
                    return e.wheelDelta / 120 // IE,Safari,Chrome
            }

            function update() {
                moving = true

                var delta = (pos - target.scrollTop) / smooth

                target.scrollTop += delta

                if (Math.abs(delta) > 0.5)
                    requestFrame(update)
                else
                    moving = false
            }

            var requestFrame = function () { // requestAnimationFrame cross browser
                return (
                    window.requestAnimationFrame ||
                    window.webkitRequestAnimationFrame ||
                    window.mozRequestAnimationFrame ||
                    window.oRequestAnimationFrame ||
                    window.msRequestAnimationFrame ||
                    function (func) {
                        window.setTimeout(func, 1000 / 50);
                    }
                );
            }()
        }

所以..。当我已经滚动了一次,但尝试使用鼠标来移动滚动条而不是鼠标滚轮时,我希望它能正常工作。

感谢您的帮助!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-06 04:52:26

看起来您可以通过在滚动计算之前将pos变量重新调整为scrollTop来修复它。

此外,还有一个bug,你的滚动可能会陷入无限的渲染循环,导致你永远不能停止动画。这是因为delta.5 < delta < 1,使得请求帧永远被调用。您不能实际移动小于1的scrollTop,因此我调整了另一个呈现循环的条件,并对delta进行了舍入

代码语言:javascript
复制
    function scrolled(e) {
        // if currently not animating make sure our pos is up to date with the current scroll postion
        if(!moving) {
            pos = target.scrollTop;
        }
        e.preventDefault(); // disable default scrolling

        var delta = normalizeWheelDelta(e)

        pos += -delta * speed
        pos = Math.max(0, Math.min(pos, target.scrollHeight - frame.clientHeight)) // limit scrolling
        if (!moving) update()
    }

    function update() {
                moving = true;
        // scrollTop is an integer and moving it by anything less than a whole number wont do anything
        // to prevent a noop and an infinite loop we need to round it
        var delta = absRound((pos - target.scrollTop) / smooth)

        target.scrollTop += delta

        if (Math.abs(delta) >= 1) {
            requestFrame(update)
        } else {
            moving = false
        }
    }

    function absRound(num) {
        if(num < 0) {
            return -1*Math.round(-1*num);
        } else {
            return Math.round(num);
        }
    }

这样,当手动调整滚动位置时,如果使用滚轮,它不会跳到它曾经所在的位置,而是将自己调整到当前滚动位置。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57365715

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档