更好的滚动体验>better-scroll

认识better-scroll

  • better-scroll是一款重点用于解决移动端(已支持PC)各种滚动场景需求的插件,可使页面滚动效果更加流畅且富有弹性
  • better-scroll是用纯JavaScript编写的,这意味着它是无依赖的

better-scroll的原理

  • BetterScroll是作用在外层wrapper容器上的,默认滚动的部分是wrapper的第一个子元素content,其它元素会被忽略。不过通过specifiedIndexAsContent配置项也可以设置滚动其它元素
  • 只有当子元素content的高度大于父元素wrapper的高度时才能滚动,为避免父元素高度是被子元素撑开,常常需要为父元素wrapper设置一个具体高度,并且设置overflow: hidden;

image-20210131010227322

使用原生滚动与better-scroll的对比

  • 使用原生滚动

img

  • 使用better-scroll

img

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表示只要是滚动,都侦测
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)
原文地址:https://www.cnblogs.com/jincanyu/p/14352240.html