首页 > 解决方案 > `mousemove` 事件中的`window.ScrollTo(...)` 会产生可怕的卡顿滚动

问题描述

我有一个自定义滚动条解决方案(在 CodePen 上查看)。

显而易见的想法是拖动自定义滚动条应该滚动页面。

试一试,看看会发生什么……奇怪的是,滚动条和页面滚动会突然在点之间卡住。

滚动过程当前在一个mousemove处理程序中:

如果我注释掉该window.scrollTo(...)行,滚动条本身就会完美平滑地移动并与光标保持一致。

相关代码

    mousemove(e) {
        if (!this.active) return;
        this.update(this.getScrollDeltaPositional(e.pageY));
        window.scrollTo({top: this.getWindowScrollTop()});
    }

    update(position, show=true, timer=true, time=0) {
        let track = this.getTrackHeight();
        this.trackPosition = Math.min(Math.max(position, 0), track);
        this.track.style.transform = `translateY(${this.trackPosition}px)`;
    }

    getWindowScrollTop() {
        let scroll = this.getDocumentScroll();
        let position = (this.trackPosition / this.root.clientHeight);
        return Math.round(scroll * position);
    }

(建议您在 CodePen 上查看完整源代码)

我认为每个滚动都会mousemove阻止mousemove事件,导致观察到突然的快照。

如何window使用自定义滚动条实现平滑滚动效果?

标签: javascripthtmlcssscrollscrollbar

解决方案


我终于找到了答案

经过太多小时尝试一切可以想象的解决方法后,我偶然发现了同样的问题:https ://css-tricks.com/forums/topic/scrolltop-inexplicably-going-haywire/ 。

正如该用户最终发现的那样,MouseEvent.pageY(这是我用来获取滚动位置的)是

相对于视口的上边缘,包括滚动偏移量

因此,滚动运动有效地放大了mousemove事件,导致滚动以指数方式加速,如演示中所示。

因此,经过半天的修改,解决方法是使用简单的 Ctrl+H...MouseEvent.clientY代替。


推荐阅读