镀铬和平滑滚动时奇怪的滚动行为

时间:2020-08-10 09:08:02

标签: javascript google-chrome scroll

我正在编写一个虚拟滚动库,遇到一个奇怪的问题,该问题仅出现在chrome中,并在chrome标志中禁用了平滑滚动,将其修复。逻辑的一部分是使用不可见的div来拉伸容器,然后滚动到顶部时,获取一些新数据,然后滚动回到旧顶部。但是,在具有平滑滚动的Chrome中,似乎scrollTop的更改不会立即应用,因此会提取多个数据并且滚动位置错误。

我在Linux上使用chrome 84.0.4147.105-1,并且在Windows上进行了测试,结果相同。有时可能很难触发,最安全的方法是将滚动条拖动到顶部附近而不触发获取并向上滚动。然后您会发现控制台值从0跳到900(向下滚动)到一个较小的数字(为什么?)并再次触发获取

const container = document.getElementById('container')
const scroller = document.getElementById('scroller')

let height = 0
let isFetching = false
const fetchData = h => {
    if (isFetching) return
    isFetching = true
    setTimeout(() => {
        height += h
        scroller.style.height = height + 'px'
        container.scrollTop += h
        isFetching = false
    }, 50)
}

fetchData(800)

container.addEventListener('scroll', ev => {
    const top = ev.target.scrollTop
    console.log(top)
    if (top <= 50) {
        fetchData(800)
    }
})
#container {
    height: 200px;
    width: 500px;
    background-color: blue;
    overflow: auto;
}

#scroller {
    width: 100%;
}
<div id="container">
     <div id="scroller"></div>
</div>

1 个答案:

答案 0 :(得分:0)

一个临时(而且确实很不雅)修复程序将fetchData更改为

const fetchData = h => {
    if (isFetching) return
    isFetching = true
    setTimeout(() => {
        height += h
        scroller.style.height = height + 'px'
        container.scrollTop += h
        isFetching = false
        setTimeout(() => container.scrollTop += h, 200)
    }, 50)
}

稍稍延迟后会再次滚动