当前位置: 首页 > 知识库问答 >
问题:

javascript - 原生JS自制的scrollbar,如何消除滑块拖动时的卡顿?

柯星华
2024-08-11

这是 事件监听,也是用docment对全局进行鼠标的移动及抬起监听了。

        const scrollStart =  (e: MouseEvent) => {
            e = e || window.Event;
            if (e.button == 0) { // 鼠标左键点击
                xPostion = e.clientX;
                originLeft = parseInt(this.scrollThumb.style.left) ? parseInt(this.scrollThumb.style.left) : 0;
                document.addEventListener('mousemove', scrollMove);
                document.addEventListener('mouseup', scrollEnd, {once: true});
            }
        }
        this.scrollThumb.addEventListener('mousedown', scrollStart);

        // let timeOutId = null;
        const scrollMove =  (e: MouseEvent) => {
            e = e || window.Event;
            e.preventDefault();
            e.stopPropagation();
            // document.removeEventListener('mousemove', scrollMove);
            // timeOutId = setTimeout(function() {
            //     document.addEventListener('mousemove', scrollMove);
            // }, 16);
            let move = e.clientX - xPostion;
            // window.requestAnimationFrame(() => {
                this.setPosition(originLeft + move); 
            // })                       
        }

        const scrollEnd = (e: MouseEvent) => {
            e = e || window.Event;
            // timeOutId = null;
            xPostion = 0;
            document.removeEventListener('mousemove', scrollMove);
        }

这是CSS,使用absolute对滑块进行定位

.scroll-track {
        position: absolute;
        left: 16px;
        top: 0;
        width: calc(100% - 52px);
        height: 20px;

        .scroll-thumb {
            position: absolute;
            left: 0;
            top: 0;
            margin: 4px 0 4px 0;
            height: 12px;
            background-color: lightgray;
        }
        .scroll-thumb:hover {
            background-color: gray;
        }
        .scroll-thumb:active {
            background-color: dimgrey;
        }
    }

共有2个答案

岑炯
2024-08-11

上面的问题我没有描述清楚,关键是这个 this.setPosition(originLeft + move); 函数我写得有问题。

原来我是这样写的

setPosition(top: number) {
    if (top >= 0 && top <= this.scrollTrack.getBoundingClientRect().height * (1 - this.ratio)) {
        this.scrollThumb.style.top = `${top}px`;
    }
    
}

由于需要判断边界,不能让滑块滑出边界,我做了鼠标滚动距离的判断,这样就导致出了边界之后,滑块不再动了,具体表现就是卡顿。所以我改了一下这个函数,完美解决。

setPosition(top: number) {
        if (top < 0) top = 0;
        if (top > this.scrollTrack.getBoundingClientRect().height * (1 - this.ratio)) {
            top = this.scrollTrack.getBoundingClientRect().height * (1 - this.ratio);
        }
        this.scrollThumb.style.top = `${top}px`;
        
    }

不再用条件判断来执行下一步操作,说白了就是把鼠标滑动的距离做个判断,超过了边界,直接把参数值固定在边界。move事件每次循环都会执行了。

长孙修远
2024-08-11

要消除滑块拖动时的卡顿,你可以考虑以下几个优化方法:

  1. 使用requestAnimationFrame
    在你的scrollMove函数中,你已经注释掉了使用requestAnimationFrame的部分。使用requestAnimationFrame可以帮助你更平滑地更新DOM,因为它会在浏览器的下一次重绘之前调用你的更新函数。这有助于减少卡顿,因为它允许浏览器优化渲染过程。

    const scrollMove = (e: MouseEvent) => {
        e = e || window.Event;
        e.preventDefault();
        e.stopPropagation();
    
        let move = e.clientX - xPostion;
        window.requestAnimationFrame(() => {
            this.setPosition(originLeft + move);
        });
    }
  2. 减少DOM操作
    确保setPosition函数内部不会进行过多的DOM操作或复杂的计算。每次移动滑块时,仅更新必要的样式属性。
  3. 优化CSS
    确保CSS属性(如transform)的使用能够由GPU加速。虽然在这个特定的例子中,你可能主要依赖left属性来定位滑块,但了解这一点对于其他可能的性能优化是有用的。
  4. 检查其他事件监听器
    确保没有其他事件监听器(如scrollresize等)在滑块拖动时触发,这些监听器可能会干扰或增加处理时间。
  5. 考虑使用节流(Throttling)或防抖(Debouncing)
    虽然在这个案例中可能不是必需的,但在某些情况下,如果mousemove事件触发得太频繁,你可以考虑使用节流或防抖技术来减少事件处理函数的调用次数。
  6. 性能分析
    使用浏览器的开发者工具(如Chrome DevTools的Performance标签页)来分析你的代码在拖动滑块时的性能表现。这可以帮助你识别任何可能导致卡顿的瓶颈。

应用上述建议后,你的滑块拖动体验应该会有所改善。特别是使用requestAnimationFrame,它通常是处理动画和流畅交互的首选方法。

 类似资料:
  • 本文向大家介绍js用拖动滑块来控制图片大小的方法,包括了js用拖动滑块来控制图片大小的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了js用拖动滑块来控制图片大小的方法。分享给大家供大家参考。具体实现方法如下: 希望本文所述对大家的javascript程序设计有所帮助。

  • 我在javaFX项目中使用了一个滑块,我有一个标签,当我移动滑块时会更新。 我希望在拖动滑块时更新标签,而不仅仅是在拖放时。 这是我的代码:

  • 如何在侧滑块中制作一些不同类型的动画。有图书馆吗?如果有图书馆,请提供我。

  • 本文向大家介绍分享一个原生的JavaScript拖动方法,包括了分享一个原生的JavaScript拖动方法的使用技巧和注意事项,需要的朋友参考一下 代码: 使用方式:

  • 能否使用原生CSS+JS实现如图的滑动效果——自动吸附和状态栏的变化(字体向左移动并变黑,部分元素消失出现以及下方的这条横线) 感谢各位大佬

  • 本文向大家介绍原生js配合cookie制作保存路径的拖拽,包括了原生js配合cookie制作保存路径的拖拽的使用技巧和注意事项,需要的朋友参考一下 主要是运用了原生js封装了一个cookie,然后使用了三个事件做拖拽,分别是onmousedown,onmousemove,onmouseup,这三个事件其中两个需要添加事件对象,也就是event,事件对象是一个不兼容的东西,所以需要处理兼容性的问题,