MST

星途 面试题库

面试题:JavaScript 实现文档元素平滑滚动到指定位置的策略

请使用JavaScript实现一个函数,该函数可以让指定的文档元素平滑滚动到某个特定的坐标位置。要求考虑到不同浏览器的兼容性,并且代码要有良好的性能优化。说明在实现过程中,如何处理滚动过程中的动画效果以及与页面其他交互的协调。
43.3万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
function smoothScrollToElement(element, targetX, targetY) {
    if (typeof window.requestAnimationFrame === 'function') {
        const startX = element.scrollLeft;
        const startY = element.scrollTop;
        const distanceX = targetX - startX;
        const distanceY = targetY - startY;
        const duration = 500; // 动画持续时间,单位毫秒
        let startTime = null;

        function step(timestamp) {
            if (!startTime) startTime = timestamp;
            const progress = timestamp - startTime;
            element.scrollLeft = startX + distanceX * (progress / duration);
            element.scrollTop = startY + distanceY * (progress / duration);
            if (progress < duration) {
                window.requestAnimationFrame(step);
            }
        }

        window.requestAnimationFrame(step);
    } else {
        // 旧浏览器兼容,使用setInterval模拟动画
        const startX = element.scrollLeft;
        const startY = element.scrollTop;
        const distanceX = targetX - startX;
        const distanceY = targetY - startY;
        const duration = 500; // 动画持续时间,单位毫秒
        const increment = 10; // 每次滚动的增量
        let currentTime = 0;
        const interval = setInterval(() => {
            currentTime += increment;
            element.scrollLeft = startX + distanceX * (currentTime / duration);
            element.scrollTop = startY + distanceY * (currentTime / duration);
            if (currentTime >= duration) {
                clearInterval(interval);
            }
        }, increment);
    }
}

处理滚动过程中的动画效果

  1. 使用requestAnimationFrame:在现代浏览器中,requestAnimationFrame是实现平滑动画的首选方式。它会在浏览器下一次重绘之前调用传入的回调函数,回调函数的参数是当前的时间戳,通过这个时间戳可以计算出动画的进度,从而实现平滑的滚动。
  2. 计算滚动距离和进度:在step函数中,通过当前时间戳与开始时间戳的差值计算出动画的进度,然后根据这个进度来计算元素应该滚动到的位置,实现平滑过渡。
  3. 旧浏览器兼容:对于不支持requestAnimationFrame的旧浏览器,使用setInterval模拟动画。通过设置一个固定的时间间隔(如10毫秒),每次在间隔内更新元素的滚动位置,逐步实现滚动效果。

与页面其他交互的协调

  1. 事件防抖和节流:在滚动过程中,如果页面有其他交互事件(如点击、拖动等),可能会与滚动动画冲突。可以使用防抖(Debounce)或节流(Throttle)技术来处理这些事件。例如,如果有一个按钮点击事件可能会触发滚动动画,使用防抖技术可以确保在短时间内多次点击按钮,只会触发一次滚动动画,避免动画的混乱。
  2. 暂停和恢复动画:可以添加逻辑来处理在其他交互发生时暂停滚动动画,交互结束后恢复动画。比如,当用户开始拖动页面元素时,暂停滚动动画,当拖动结束后,继续滚动到目标位置。
  3. 全局状态管理:如果页面有多个地方可能触发滚动动画,或者与其他复杂的交互逻辑相关联,可以使用全局状态管理(如Redux等,在大型项目中)来协调不同部分之间的交互,确保滚动动画与其他交互之间的一致性和协调性。