如何避免用户滚动主内容时中断navbar的scrollIntoView滚动动画
问题原因分析
scrollIntoView默认行为是调整元素在整个页面视口的位置,你仅指定了垂直方向的block参数时,浏览器会优先调整垂直位置对齐,这就是页面先上下滚动再执行横向滚动的原因。- 浏览器规范明确规定:用户主动触发的任意滚动操作,都会中断所有正在执行的JS触发的平滑滚动,避免滚动冲突影响用户操作,该逻辑是浏览器底层默认行为,没有办法强制
scrollIntoView不被中断。
解决方案
直接操作导航栏滚动容器的scrollLeft属性,两个滚动上下文完全独立,用户滚动主内容不会影响导航栏的横向滚动,也不会触发页面的垂直滚动:
修改后的JS代码
const first = document.querySelector('#first') const last = document.querySelector('#last') const navList = document.querySelector('nav ul') let atLast = false // 封装导航栏滚动方法,仅横向滚动,不影响页面垂直滚动 function scrollNavToElement(el) { // 计算元素居中需要的滚动距离 const elOffsetLeft = el.offsetLeft const containerVisibleWidth = navList.clientWidth const elWidth = el.clientWidth const targetLeft = elOffsetLeft - (containerVisibleWidth / 2) + (elWidth / 2) navList.scrollTo({ left: targetLeft, behavior: 'smooth' }) } setInterval(() => { if (!atLast) { scrollNavToElement(last) atLast = true } else { scrollNavToElement(first) atLast = false } }, 1000)
补充说明
原有CSS、HTML代码无需修改,该方案的滚动逻辑完全限定在导航栏的滚动容器内,和页面主滚动是完全独立的两个上下文,用户滚动主页面的垂直滚动完全不会打断导航栏的横向平滑动画。
内容的提问来源于stack exchange,提问作者Lars Flieger
相关产品推荐
相关产品推荐

