smooth-scrolling - 在其他帖子中发现的滚动平滑代码中发现错误但不知道如何修复

标签 smooth-scrolling

我在我的 friend Google 上搜索了一些代码来进行平滑滚动并找到了这个:Smooth vertical scrolling on mouse wheel in vanilla 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);
                    }
                );
            }()
        }

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

感谢您的帮助!

最佳答案

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

此外还有一个错误,您的滚动可能会卡在无限渲染循环中,导致您永远不会停止动画。这是由于 delta正在.5 < delta < 1使请求框架永远被调用。你实际上不能移动 scrollTop任何小于 1 的东西,所以我调整了另一个渲染循环的条件并四舍五入 delta

    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);
        }
    }

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

关于smooth-scrolling - 在其他帖子中发现的滚动平滑代码中发现错误但不知道如何修复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57365715/

相关文章:

java - 如何加速 Android 多行 Edittext 中的平滑滚动?

jQuery平滑div滚动左侧滚动速度比右侧快很多

iOS 上的 JQuery Mobile 滚动不流畅

android - 协调器布局滚动行为异常

android - Recyclerview 在滚动完成之前不能顺利滚动

javascript - 如何在整个页面上创建平滑的滚动效果?

jQuery 动画 : change speed while it is running

JavaScript 平滑滚动解释

html - IE11 上的奇怪边距问题 - 溢出和平滑滚动可能相关

jquery垂直鼠标滚轮平滑滚动