Vue---结合better-scroll

姜景焕
2023-12-01

一、better-scroll基本使用

1.基础用法

 new BScroll('.wrapper')

其中wrapper为外层容器,而他只能含有一个子元素。例如:

<div class="wrapper">
  <ul class="content">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
  </ul>
  <!-- 这里可以放一些其它的 DOM,但是会被忽略,且不会影响content部分滚动 -->
</div>

content元素就是滚动元素,它是wrapper的唯一子元素,且其高度必须大于wrapper的高度(若为横向滚动则content宽度必须大于wrapper宽度),否则无法滚动。

2.进阶用法

① 图片轮播
------说到图片轮播,我们首先可能想到的就是经典的 Swiper.js,而事实上我们其实还可以使用更加轻量级的 better-scroll.js 来替代。例如:

1.结构表
<div class="wrapper">
    <ul class="content">
        <li><img src="./images/img1.jpg" alt=""></li>
        <li><img src="./images/img2.jpg" alt=""></li>
        <li><img src="./images/img3.jpg" alt=""></li>
    </ul>
</div>

2.样式表(swiper.js不需要手写样式)
.wrapper{ width: 600px; height: 320px; overflow: hidden;}
.content{ margin: 0; padding: 0; width: 1800px; overflow: hidden;}
.content li{ float: left; width: 600px; list-style: none;}
.content li img{ display: block; width: 100%;}

3.javascript代码
new BScroll('.wrapper', {
  scrollX: true,
  scrollY: false,
  snap: {  // 滑动切换的一些配置
    speed: 800,  // 滑动切换的速度
    easing: {  // 滑动切换的动画效果
      style: 'ease-in'
    },
    threshold: 0.5,  // 滑动切换到超过一半时切换到下一屏
    stepX: 600,  // 横向切换距离为轮播图宽度
  }
});

② 整屏滚动
------有了上面图片轮播的案例,整屏滚动看起来就简单了许多,因为 better-scroll.js 本身默认就是竖屏滚动,因此配置会更加简洁。

1.结构表
<div class="wrapper">
    <ul class="content">
        <li>第一屏</li>
        <li>第二屏</li>
        <li>第三屏</li>
    </ul>
</div>

2.样式表(swiper.js不需要手写样式)
body{ margin: 0;}
.wrapper{ height: 100vh; overflow: hidden;}
.content{ margin: 0; padding: 0;}
.content li{ display: flex; justify-content: center; align-items: center; height: 100vh; list-style: none; font-size: 50px; font-weight: bold; color: #fff;}
.content li:nth-child(1){ background: #f00;}
.content li:nth-child(2){ background: #0f0;}
.content li:nth-child(3){ background: #00f;}

3.javascript代码
new BScroll('.wrapper', {
  snap: {  // 滑块切换的一些配置
    threshold: 0.5,  // 滑动切换到超过一半时切换到下一屏
    stepY: window.innerHeight  // 纵向切换距离为窗口高度
  }
});

② 多屏多向滚动
------类似于九宫格滚动。

1.结构表
<div id="app">
    <article class="container">
        <section class="section"></section>
        <section class="section"></section>
        <section class="section"></section>
        <section class="section"></section>
        <section class="section"></section>
        <section class="section"></section>
        <section class="section"></section>
        <section class="section"></section>
        <section class="section"></section>
    </article>
</div>

2.样式表(swiper.js不需要手写样式)
// Less代码
body{ margin: 0;}
body,
#app{
  width: 100vw; height: 100vh; overflow: hidden;
}
.container{
  display: grid;
  width: 300vw;
  height: 300vh;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
}
.section{
  height: 100vh;
}
.loop(@i) when (@i <= 9){
  .section:nth-of-type(@{i}){
    background: url("../images/puzzle_img@{i}.jpg") no-repeat center; background-size: cover;
  }
  .loop(@i+1);
}
.loop(1);

3.javascript代码
new BScroll('#app', {
  scrollX: true,
  bounce: false,
  snap: {
    threshold: 0.5,
    stepX: window.innerWidth,
    stepY: window.innerHeight
  }
});

二、better-scroll常见问题

1.滚动问题

①无法滚动:内容长度是否大于容器长度
②滚动异常:滚动区域长度是由scrollerHeight属性决定的

  • 原因:页面加载时,scrollerHeight属性开始计算,但图片未加载完毕,所以图片的高度未计算入scrollerHeight内。
  • 解决方案:
    • a. 给img嵌套外层容器并设置一定高度
    • b. 给img绑定监听load事件,在加载完毕后执行scroll的refresh方法
  • PS:多张图片加载触发多次load事件,执行N次load的回调函数中的refresh方法,造成性能浪费。可以使用防抖函数
deshake(fns,delay){// fns为refresh方法
   let timer = null
   return function(...args){
     if(timer) clearTimeout(timer);
     timer = setTimeout(()=>{
       fns.apply(this,args)
     },delay)
   }
},

③refresh方法为underfined:在mouted生命周期中使用,而不是created。

2.点击问题

  • 默认option—{click:false}此时button可以监听,其他标签无法监听点击事件

3.上拉/下拉加载

①上拉加载

  • 设置pullUpLoad为true或者赋值Obj

pullUpLoad: {threshold: -30 // 当上拉距离超过30px时触发 pullingUp 事件 }
or
pullUpLoad: true

  • 绑定pullingUp事件
this.scroll.on('pullingUp', () => {
  // 做些事件
  this.scroll.finishPullUp()// 做完事情后调用此方法告诉BS本次上拉加载完成,下次加载才能开始
 }

②下拉加载

  • 设置pullDownRefresh为true或者赋值Obj

pullDownRefresh: {
threshold: -30 // 当上拉距离超过30px时触发 pullingUp 事件
stop: 20 // 回弹停留在距离顶部20px的位置
}
or
pullDownRefresh: true

  • 绑定pullingDown事件
this.scroll.on('pullingDown', () => {
  // 做些事件
  this.scroll.finishPullDown()// 做完事情后调用此方法告诉BS本次下拉加载完成,下次加载才能开始
}

4.keep-alive卡顿

  • 返回路由可能发生:1.滚动到顶部 2. 滚动到离开时的位置
  • 设置以下生命周期钩子可以保证滚动到离开时的位置
activated() {
  this.$refs.scroll.refresh();
  this.$refs.scroll.scrollTo(0, this.saveY, 0)
},
deactivated() {
  //保存Y值
  this.saveY = this.$refs.scroll.scroll.y
},

5.二维码识别

  • 因为 better-scroll 会阻止浏览器的默认行为,比如页面原生的滚动功能,当然也包括长按识别二维码的功能,所以为了局部解除禁止,须添加以下配置:
preventDefaultException: {
  className: /^(此处填二维码图片的class属性)$/
}

// 例如:<img class="qrcode" src="./images/qrcode.png" />
// preventDefaultException: {
//  className: /^qrcode$/
// }

三、常用配置

1.option参数配置

{
  startX: 0 // (默认值:0) 表示X轴滚动的起始值
  startY: 0 // (默认值:0) 表示Y轴滚动的起始值
  click: true,  // 元素可触发点击事件
  scrollX: false,  // 横向可滑动,默认为false
  scrollY: true,  // 纵向可滑动,默认为true
  freeScroll: false //(默认值:false) 自由方向滚动
  momentum: true // (默认值:true) 当快速滑动时是否开启滑动惯性
  bounce: true // (默认值:true) 是否启用回弹动画效果
  bounceTime: 700 // (默认值:700,单位:ms)回弹动画的动画时长。 
  preventDefault: true // 是否阻止默认事件
  preventDefaultException: {  // 设置局部某元素原生事件不被禁止(默认preventDefault为true)
    className: 【正则表达式】
  },
  snap: {  // 滑动切换的一些配置
    speed: 800,  // 滑动切换的速度
    easing: {  // 滑动切换的动画效果
      style: 'ease-in'
    },
    threshold: 0.5,  // 滑动切换到超过一半时切换到下一屏
    stepX: window.innerWidth,  // 横向切换距离为窗口宽度
    stepY: window.innerHeight  // 纵向切换距离为窗口高度
  },
  probeType: 0
    //可选值:1、2、3; (默认值: 0 不派发scroll事件)想要获取滚动实时位置时派发事件的截流情况
    // 1 滚动的时候会派发scroll事件,会截流;
    // 2 滚动的时候实时派发scroll事件,不会截流; 
    // 3 除了实时派发scroll事件,在swipe的情况下仍然能实时派发scroll事件;
    // 当 probeType 为 1 的时候,会非实时(屏幕滑动超过一定时间后)派发scroll 事件;当 probeType 为 2 的时候,会在屏幕滑动的过程中实时的派发 scroll 事件;当 probeType 为 3 的时候,不仅在屏幕滑动的过程中,而且在 momentum 滚动动画运行过程中实时派发 scroll 事件。如果没有设置该值,其默认值为 0,即不派发 scroll 事件。
}

2.event事件

  • beforeScrollStart - 滚动开始之前触发
  • scrollStart - 滚动开始时触发
  • scroll - 滚动时触发
  • scrollCancel - 取消滚动时触发
  • scrollEnd - 滚动结束时触发
  • touchend - 手指移开屏幕时触发
  • flick - 触发了 fastclick 时的回调函数
  • refresh - 当 better-scroll 刷新时触发
  • destroy - 销毁 better-scroll 实例时触发

3.函数列表

  • scrollTo(x, y, time, easing)
    滚动到某个位置,x,y 代表坐标,time 表示动画时间,easing 表示缓动函数
  • scrollToElement(el, time, offsetX, offsetY, easing)
    滚动到某个元素,el(必填)表示 dom 元素,time 表示动画时间,offsetX 和 offsetY 表示坐标偏移量,easing 表示缓动函数
  • refresh()
    强制 scroll 重新计算,当 better-scroll 中的元素发生变化的时候调用此方法
  • getCurrentPage()
    snap 为 true 时,获取滚动的当前页,返回的对象结构为 {x, y, pageX, pageY},其中 x,y 代表滚动横向和纵向的位置;pageX,pageY 表示横向和纵向的页面索引。用法如:getCurrentPage().pageX
  • goToPage(x, y, time, easing)
    snap 为 true,滚动到对应的页面,x 表示横向页面索引,y 表示纵向页面索引, time 表示动画,easing 表示缓动函数(可省略不写)
  • enable()启用 better-scroll,默认开启
  • disable() 禁用 better-scroll
  • destroy() 销毁 better-scroll,解绑事件
 类似资料: