H5中当页面滚动

开发中遇到这样一个需求,有两个div,当页面滚动时,第一个div隐藏,当页面停止滚动时,div显示,当滚动大于某个值时,第二个div显示(这种情景多用于商品列表,当用户点击按钮时,回到最顶部)

首先先在data中定义变量(isshow:控制第一个div;btnFlag:控制第二个div) 

 mounted() {
    window.addEventListener("scroll", this.scrollToTop);
  },
  beforeDestroy() {
    //离开页面时取消监听,防止内存泄露
    window.removeEventListener("scroll", this.scrollToTop);
  },
 watch: {
    scrollTop(newValue, oldValue) {
      setTimeout(() => {
        if (newValue == window.scrollY) {
          //滚动结束
          this.isshow = true;
          //延时执行后当newValue等于window.scrollY,代表滚动结束
          this.oldScrollTop = newValue; //每次滚动结束后都要给oldScrollTop赋值
        }
      }, 20); //必须使用延时器,否则每次newValue和window.scrollY都相等,无法判断,20ms刚好大于watch的侦听周期,故延时20ms
      if (this.oldScrollTop == oldValue) {
        //滚动开始
        //每次滚动开始时oldScrollTop与oldValue相等
        this.isshow = false;
      }
    }
  },
methods:{
     backTop() {
      let timer = setInterval(() => {
        let ispeed = Math.floor(-this.scrollTop / 5);
        document.documentElement.scrollTop = document.body.scrollTop =
          this.scrollTop + ispeed;
        if (this.scrollTop === 0) {
          clearInterval(timer);
        }
      }, 16);
    },
    // 为了计算距离顶部的高度,当高度大于300显示回顶部图标,小于700则隐藏
    scrollToTop() {
      let scrollTop =
        window.pageYOffset ||
        document.documentElement.scrollTop ||
        document.body.scrollTop;
      this.scrollTop = scrollTop;
      if (scrollTop > 300) {
        this.btnFlag = true;
      } else {
        this.btnFlag = false;
      }
    }
}

在电脑调式的时候,效果很好。

在安卓上效果也还行,但是在ios上会存在第一个div在停止滚动之后,闪烁几下在显示。

百度了一下,说这是scroll在ios上的通病~

后来我觉得用better-scroll,这个插件已经很成熟了,在安卓和ios上表现都很好,应该能够解决我的问题,加上我之前项目本身就引入了better-scroll,所以我就抱着试试的态度

先引入better-scroll

import BScroll from 'better-scroll'

再data中定义

 scrollY:''

在mounted中初始化better-scroll,用setTimeout或者this.$nextTick等到dom渲染成功了再初始化

 this.$nextTick(() => {
      this.initScroll();
    });

methods中

 initScroll() {
      this.$nextTick(() => {
        if (!this.$refs.listWrapperL) {   //如果没有获取到dom就不继续,防止找不到dom报错
          return;
        }
        //配置: 可根据个人需求
        this.listScroll = new BScroll(this.$refs.listWrapperL, {
          probeType: 3, // 是否会截流scroll事件
          scrollY: true, // 是否开启Y轴滚动方向
          click: true, // 是否开启点击事件
          useTransition: false, // 防止iphone微信滑动卡顿
          bounce: true, // 是否启用回弹动画效果
          momentumLimitDistance: 5 // 符合惯性拖动的最小拖动距离
        });
        this.listScroll.on("scroll", pos => {
          this.isshow = false;    //控制第一个div滚动是隐藏
          // 使用abs绝对值(否则 pos.y拿到值是负数)
          this.scrollY = Math.abs(Math.round(pos.y));
          if (this.scrollY >= 300) {
            this.btnFlag = true;   //控制第二个div滚动到一定距离显示
          } else {
            this.btnFlag = false; //控制第二个div滚动到一定距离隐藏
          }
        });
        this.listScroll.on("scrollEnd", pos => {
          console.log("页面停止");
          this.isshow = true;   //控制第一个div滚动是显示
        });
      });
    },

现在我们两个div都能满足需求的动态显示与隐藏了,现在还差一个功能,就是点击第二个div的时候要回到页面顶部

 backTop() {
      this.listScroll.scrollTo(0, 0, 1000);
    }

我用下来遇到的问题就是页面滚动不了?

然后看了官方文档,说内容高度一定要大于外面的盒子高度才能滚动,这也是better-scroll滚动的原理。

于是我那些我的调式工具,一个块一个块点,没问题啊,我的内容高度已经是超出外面盒子的高度了,即使我给外面的盒子设置400px的高度,依旧不能滚动。然后我不知道是在哪里看到的,说better-scroll只作用于第一个div,然后我再看看我的html结构

 

 样式代码

.listWrapperL {
  width: 100%;
  height: 100%;
  overflow: hidden;
  -webkit-overflow-scrolling: touch;
}

最后在页面离开的时候一定要销毁一下better-scroll,防止内存泄露

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值