认识better-scroll
- better-scroll是一款重点用于解决移动端(已支持PC)各种滚动场景需求的插件,可使页面滚动效果更加流畅且富有弹性
- better-scroll是用纯JavaScript编写的,这意味着它是无依赖的
better-scroll的原理
- BetterScroll是作用在外层wrapper容器上的,默认滚动的部分是wrapper的第一个子元素content,其它元素会被忽略。不过通过specifiedIndexAsContent配置项也可以设置滚动其它元素
- 只有当子元素content的高度大于父元素wrapper的高度时才能滚动,为避免父元素高度是被子元素撑开,常常需要为父元素wrapper设置一个具体高度,并且设置
overflow: hidden;
使用原生滚动与better-scroll的对比
- 使用原生滚动
- 使用better-scroll
BetterScroll的基本使用
- 首先当然得安装插件
npm install better-scroll --save
- BetterScroll提供了一个类,实例化时需传入一个必须参数,这个参数即是要滚动的区域的外层元素,传入方式类似于
querySelector()
import BScroll from 'better-scroll'
mounted() {
const bscroll = new BScroll('.wrapper', {
// 可选参数,下文说明
probeType: 3, //侦测滚动的实时位置
click: true, //侦测点击
pullUpLoad: true //侦测上拉加载更多
})
}
BetterScroll传入对象中的常用属性
- ①probeType
- 侦测实时滚动的位置,监听scroll事件
- 0或1都是表示不侦测
- 2表示在手指滚动的过程中侦测,手指离开后的惯性运动不侦测
- 3表示只要是滚动,都侦测
- 侦测实时滚动的位置,监听scroll事件
bscroll.on('scroll', (position) => {
console.log(position)
})
- ②click
- 侦测点击,默认不能点击,监听click事件
bscroll.on('scroll', () => {
console.log('默认不能点击')
})
- ③pullUpLoad
- 侦测上拉加载更多,默认只能上拉一次,监听pullingUp事件
- 调用finishPullUpLoad()方法可多次上拉
bscroll.on('pullingUp', () => {
console.log('上拉加载更多')
// 此时发送网络请求,请求更多页的数据
// 为防止网络拥堵使用户频繁的上拉加载导致频繁的请求网络,因此设置个1s的定时
setTimeout(() => {
bscroll.finishPullUp()
}, 1000)
}
常见问题
-
①在vue的内容页中,常常会出现的问题是滚动时卡顿
-
原因常常是图片还没下载完时,内容页高度不够,而此时已经将外层容器高度固定了。举个例子,假设外层容器高度为500px,原本的内容页高度为2000px,而由于图片未下载完导致内容页此时高度只有600px,当内容页滚动时,滚动到600px就会卡顿
-
通过查看当前滚动对象的scrollHeight属性可以判断是否是该原因,
this.$ref.bscroll.scrollHeight
-
解决方式是监听每一张图片是否加载完成,只要有一张图片加载完成,就执行一次refresh()
-
那么新问题又来了,如何监听图片加载完成?
-
vue中的监听方式:
@load='方法名'
,调用scroll对象中的refresh()方法
<img v-lazy="showImage" alt="" @load="imageLoad"> methods: { imageLoad() { this.$ref.bscroll.refresh() } }
- 如果内容页图片过多,可能需要多次refresh(),这样会影响性能。因此对于频繁的refresh操作,需进行防抖操作防抖debounce/节流throttle
-
//解决刷新频繁的防抖函数
export function debounce(fn, delay) {
// 记录上一次的延时器
var timer = null;
var delay = delay || 200;
return function() {
let args = arguments;
// 清除上一次延时器
if (timer) clearTimeout(timer)
timer = setTimeout(function() {
fn.apply(this,args)
}, delay);
}
}
import {
debounce
} from 'common/utils'
const refresh = debounce(this.$refs.scroll.refresh, 100)