问题
最近在写一个自动更新的消息列表组件,里面使用到了 scrollTo
这个方法,scrollTo
里面呢,有一种平滑过渡的模式:
this.$refs.scroll.scrollTo({ top: 100, behavior: 'smooth' })
这种模式会让你在设置滚动距离时自带滑动的过渡效果,像“回到顶部
” 或者 “卯点滑动
” 这些功能,用它来实现会异常简单。
但是呢,这个方法也有一些缺点:
- 过渡时间无法自定义
- 没有提供回调函数插口
这会导致一些问题,比如消息列表组件在每次有更新推送过来时,需要先将列表滚动至顶部,然后再执行新消息的动画,因为我们现在既没有办法定义 scrollTo
的过渡执行时间,又没有回调函数插口可用,所以我们不知道列表滚动至顶部什么时候执行完的,什么时候执行新消息的动画就成了个坑。
这个问题貌似有点偏蔽,以至于我找了一圈,显有收获,最后终于在一个大哥的老帖里发现了希望,大哥说,这个时间呢,没有的,这个回调呢,也是没有的,但是,它有事件!!!
划重点了啊,事件
,scrollTo
这个方法在执行完成之后,会触发 scrollend
事件。
哎呀呀,千帆依始尽入夜,一浆划得天地开。接下来,我们就来来好好利用一下这个事件:
// 监听滚动结束
scrollWait(El) {
return new Promise(resolve => {
const wait = () => {
El.removeEventListener('scrollend', wait)
resolve(true)
}
El.addEventListener('scrollend', wait)
})
},
// 滚动
async goScroll (top = 0) {
clearTimeout(this.scrollTimeout)
const El = this.$refs.scroll
El.scrollTo({ top, behavior: 'smooth' })
await this.scrollWait(El)
this.scrollTimeout = setTimeout(() => {
// 其他执行逻辑
}, 300)
}
完成