zoukankan      html  css  js  c++  java
  • vue+Better-scroll实现滚动位置保持并对页面切换效果进行优化

    前言:

    环境限制,只能用hash模式,所以不能直接用vue自身的页面缓存。

    如果要保持页面滚动位置,可以在页面滚动结束后将滚动距离保存到缓存中,然后在下次加载页面的时候自动滚动指定距离。

    这里以Better-scroll2.0为例进行说明。

    示例代码:

      1 <template>
      2   <div class="page w100 h100">
      3     <!--数据列表容器-->
      4     <div class="h100 wrapper pRelative" ref="wrapper">
      5       <div class="content pRelative">
      6         <router-link class="item lh30 w100" v-for="(item,index) in list" :key="index" :to="{name:'GoodDetail'}">
      7           <div class="iblock w30"><img :src="item.img" /></div>
      8           <div class="goodInfo w70 tl">
      9             <p class="ellipsis w90 f15">{{item.title}}</p>
     10             <p class="ellipsis_mul w90 f13 lh15">{{item.desc}}</p>
     11           </div>
     12         </router-link>
     13       </div>
     14     </div>
     15     <!--数据列表容器 end-->
     16     <!--页面切换蒙层-->
     17     <div v-show="showWhiteBoard==1" class="pAbsolute w100 h100 bgWhite">
     18       <van-loading type="spinner" style="margin-top:100px;" />
     19     </div>
     20     <!--页面切换蒙层 end-->
     21   </div>
     22 </template>
     23 
     24 <script>
     25   import http from '@/api/index'
     26   import BScroll from "@better-scroll/core"
     27   import {
     28     Loading
     29   } from 'vant';
     30   export default {
     31     name: "Better-Scroll",
     32     data() {
     33       return {
     34         list: '', //数据列表
     35         scroll: '', //滚动实例
     36         showWhiteBoard: '' //页面切换蒙层开关
     37       }
     38     },
     39     components: {
     40       [Loading.name]: Loading,
     41     },
     42     created() {
     43       this.init()
     44     },
     45     methods: {
     46       init() {
     47         http.getGoodsList({
     48           goodId: 1001
     49         }).then(data => {
     50           if (data && data.goodsList) {
     51             this.list = data.goodsList
     52             this.doScroll()
     53           }
     54         })
     55       },
     56       /**
     57        * 列表滚动事件处理
     58        * @param {Object} list
     59        */
     60       doScroll: function() {
     61         //添加滚动处理
     62         this.$nextTick(() => {
     63           if (!this.scroll) {
     64             this.scroll = new BScroll(this.$refs.wrapper, {
     65               preventDefault: false, //这个不能有,ios系统会受框架层滑动影响
     66               click: true
     67             })
     68 
     69             //自动滚动
     70             let scrollY = localStorage.getItem("scrollY")
     71             if (scrollY) {
     72               //显示页面切换的蒙板
     73               this.showWhiteBoard = 1
     74               //滚动指定距离
     75               this.scroll.scrollTo(0, scrollY, 300, undefined);
     76               //隐藏页面切换的蒙板
     77               setTimeout(() => {
     78                 this.showWhiteBoard = 0
     79               }, 300)
     80             }
     81 
     82             //保存滚动位置
     83             this.scroll.on("scrollEnd", poy => {
     84               let scrollY2 = poy && poy.y
     85               if (scrollY2) localStorage.setItem('scrollY', scrollY2)
     86             });
     87           } else {
     88             this.scroll.refresh()
     89             this.scroll.scrollTo(0, 0, 100, undefined)
     90           }
     91         })
     92       }
     93     }
     94   }
     95 </script>
     96 
     97 <style lang="scss" scoped>
     98   .page {
     99     $bc: #ffffff;
    100     $fc: #000000;
    101     overflow: hidden;
    102 
    103     @for $i from 0 to 30 {
    104       .item:nth-child(#{$i}) {
    105         background-color: $bc - $i*10;
    106       }
    107     }
    108 
    109     .item {
    110       display: flex;
    111       padding: 25px;
    112 
    113       img {
    114         width: 150px;
    115         height: 150px;
    116       }
    117 
    118       .goodInfo {
    119         margin-left: 20px;
    120       }
    121     }
    122   }
    123 </style>

    注:例中使用了Better-scroll2.0处理页面滚动,以及页面的自动滚动。

    体验优化:

    BS滚动指定距离会有一个滚动过程,这样体验就比较差了,如下:

     解决这个问题,可以在页面加载处理自动滚动的时候添加一个蒙版,遮住这个滚动过程,这样页面切换就会好很多。相关代码如下:

    1     <!--页面切换蒙层-->
    2     <div v-show="showWhiteBoard==1" class="pAbsolute w100 h100 bgWhite">
    3       <van-loading type="spinner" style="margin-top:100px;" />
    4     </div>
    5     <!--页面切换蒙层 end-->
     1 //自动滚动
     2 let scrollY = localStorage.getItem("scrollY") if (scrollY) {
     3     //显示页面切换的蒙板
     4     this.showWhiteBoard = 1
     5     //滚动指定距离
     6     this.scroll.scrollTo(0, scrollY, 300, undefined);
     7     //隐藏页面切换的蒙板
     8     setTimeout(() = >{
     9         this.showWhiteBoard = 0
    10     },300)
    11 }

    如上,蒙版中使用了vant的loading,这样比空白页面更好些(如果运行环境本身对页面切换已经做了loading,那就不用了)。

    关闭蒙版的时间设置为自动滚动后300ms,这个时间滚动基本上已经完成了(多次验证结果)。

    优化后的效果如下:

    如上,页面切换没有明显的页面滚动了(使用mock.js模拟数据,所以数据有更新,会有轻微滑动,真实接口数据则不会)。

    后记:

    Better-Scroll1.x出现ios兼容性问题,升级到2.x,也会有一些问题,处理起来还是有点麻烦的,决定弃用了。

    建议使用vant组件库,大厂产品还是比较靠谱些,上拉加载、下滑刷新这些用起来都比较简单,效果也不错。

    个人原创博客,转载请注明来源地址:https://www.cnblogs.com/xyyt
  • 相关阅读:
    栈和队列_leetcode23
    Android 广播
    Android Service
    Logcat monkey命令
    设计模式-观察者模式
    Android之Fragment优点
    Android架构: MVC 新浪微博
    Android消息处理机制(Handler、Looper、MessageQueue与Message)
    Android Annotations Eclipse 配置 (3)
    Android Annotations(2)
  • 原文地址:https://www.cnblogs.com/xyyt/p/14441858.html
Copyright © 2011-2022 走看看