学习之余,发现了一个比较好的滚动组件 BetterScroll,在移动端、PC端都有很好的体验效果。就拿出来分享一下:BetterScroll官网。源码托管自 GitHub:BetterScroll。中文文档:BetterScroll文档
该组件在 GitHub 有这样依据介绍:inspired by iscroll, and it supports more features and has a better scroll perfermance.(灵感来源于iscroll...)。iscroll 也是一个比较好的滚动组件,但是在 3 Jan 2017停更了。所以在这之后,国人就开发了 BetterScroll 这么一个优秀的组件,截止2020.7.1还在继续更新,而且该组件在 iscroll之上也添加了更多的一些功能,效果还是不错的。
在开发中,总会遇到对图片列表的上拉加载需求。但是在引入 BetterScroll 组件时,却 导致图片类型列表上拉到一部分时,出现拉不上去的Bug。
经过分析,是Vue在加载数据的过程中,由于网络的原因,图片的加载都会有个先后顺序(或因为网络延迟,导致的图片迟了几百毫秒显示)。然而 BetterScroll 组件是在图片还未加载完成时,就已经完成了对滚动区域的高度计算,当图片真正加载完成时,导致高度计算有问题,从而出现拉不上去的Bug。 (实际高度>已计算的高度,导致拉不上去)
BetterScroll 组件中,提供了refresh()这个方法,即:重新计算 better-scroll,当 DOM 结构发生变化的时候务必要调用确保滚动的效果正常。
最终解决方法就是:在每次加载图片完成时,重新计算一下 DOM 结构的高度。
原生JS在<img onload="xxx">标签中,onload 这个属性就是用来监听图片是否加载完成的。Vue 中我们可以通过 @load="xxx" 的方式来监听。步骤如下:
在包含<img> 的 Vue 子组件中,通过 @load="isLoadOK" 的方式来监听图片是否加载完成;在 methods 中定义方法 isLoadOK ,然后通过 $emit 的方式,将事件传到父组件(兄弟组件请使用bus总线),父组件通过 this.$on() 的方式调用 this.refs.scroll.refresh() 就可以完美解决。如果一张图片加载完成就调用一次 refresh()方法,显然影响性能。此处我们可以使用 JS防抖函数来处理。
所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
/** * 定义防抖动函数,防止函数调用频繁,图片加载完成后,再进行重新计算高度的刷新 */ export function debounce(func, delay) { let timer; return function(...args) { if (timer) clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args) }, delay) } }然后,将父组件中,this.$on('imageLoad', this.$refs.scroll.refresh()) 这种方式稍微修改一下即可,如下所示:
<script> export default { //省略部分代码 //在加载完成时, mounted(){ // 1.图片加载完成的事件监听 const refresh = debounce(this.$refs.scroll.refresh, 50) this.$on('imageLoad', () => { refresh() }) } }参考文章:
JS 防抖函数和节流函数介绍
博主写作不易,加个关注呗
求关注、求点赞,加个关注不迷路 ヾ(◍°∇°◍)ノ゙
博主不能保证写的所有知识点都正确,但是能保证纯手敲,错误也请指出,望轻喷 Thanks♪(・ω・)ノ