评论

小程序页面吸顶效果、右下角悬浮按钮等隐藏显示切换时不卡顿的实现方法

小程序页面吸顶效果、右下角悬浮按钮等隐藏显示切换时不卡顿的实现方法

使用的api及页面方法

api:wx.createSelectorQuery、wx.createIntersectionObserver

页面方法:onPageScroll

为什么使用以上方法?

wx.createSelectorQuery:主要解决页面渲染后保证所涉及的元素能百分百渲染到屏幕上,这里打包一个异步方法。

getElement(elm, component) {
    const _this = this;
    return new Promise((resolve, reject) => {
      let ss = setInterval(function() {
        let Qy = component ? _this.createSelectorQuery() : wx.createSelectorQuery();
        let a = Qy.select(elm).boundingClientRect(function(res) {
          if (res) {
            clearInterval(ss)
            resolve(res)
          }
        }).exec();
      }, 50);
    });
  }

wx.createIntersectionObserver与onPageScroll的作用:
单纯使用onPageScroll切换隐藏显示状态必然会高频率使用setData导致页面卡顿。如果只是在wx.createIntersectionObserver与onPageScroll中隐藏或者显示,即确保每个方法中只setData一次,那么卡顿的现象就不会出现。
以下wx.createIntersectionObserver仅作显示元素

onCreateIntersectionObserver(component,elm) {
    const _this = this;
    this.getElement(elm||".tr-fixed", component).then(res => {
      _this.setData({
        fixed_top: res.top //记录一直显示的元素的top值
      });
      _this.IntersectionObserver = component ? _this.createIntersectionObserver() : wx.createIntersectionObserver()
      _this.IntersectionObserver.relativeTo(".top-transparent", {
        bottom: 2
      }).observe(elm||'.tr-fixed', (res) => {
      //显示吸顶
        const {
          fixed_show
        } = _this.data;
        if (fixed_show === false) {
          _this.setData({
            fixed_show: true
          });
        }
        //显示吸顶
      })
    });
  }

上面代码中:
.top-transparent是自定义参照区域。
.tr-fixed或elm为切换隐藏与显示的元素(事先写好顶部浮动,隐藏起来,这里并没有css仅作为监听对象)
wxml基本代码:

<view class="top-transparent">页面顶部透明参照元素</view>

<view class="tr-fixed">一直显示的部分(滚动的scrollTop小于此元素的top值则隐藏,如果监测到与透明的参照元素交叉则显示)</view>

<view class="fixed-view" wx:if="{{fixed_show}}">隐藏的部分(与一直显示的部分一模一样)</view>
.top-transparent{
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 20px;
  background: transparent;//透明
  pointer-events: none; //保证此元素所有点击事件无效,即点击事件都穿透到比它层级低的元素上
}

以下onPageScroll仅作隐藏元素

onPageScroll(e) {
    const {
      fixed_top,
      fixed_show
    } = this.data
    // 隐藏吸顶头部
    if (fixed_top != undefined && fixed_show) {
      if (e.scrollTop <= fixed_top) {
        this.setData({
          fixed_show: false
        })
      }
    }
    // 隐藏吸顶头部
  },

代码片段:
https://developers.weixin.qq.com/s/oUhsfCmP76au

最后一次编辑于  2019-08-14  
点赞 1
收藏
评论

8 个评论

  • 我现在只想好好睡一觉
    我现在只想好好睡一觉
    2020-03-12
     onPageScroll=(data)=>{
    
        if(data.scrollTop>160&&pageStatus===true){
             return
        }
        if(data.scrollTop<160&&pageStatus===false){
          return
          }
    
        if(data.scrollTop>160){
          this.setData({
            bbb:'吸顶'
          })
          pageStatus = true
        }else{
          this.setData({
            bbb:'不吸'
          })
          pageStatus = false
        }
      }
    

    这个判断不是可以么,只在滚动到指定位置时调用setData

    2020-03-12
    赞同 1
    回复 7
    • 111
      111
      2020-03-15
      高频率使用setData导致页面卡顿
      2020-03-15
      回复
    • 我现在只想好好睡一觉
      我现在只想好好睡一觉
      2020-03-16回复111
      这个只在滑动到指定位置的时候调用一次就行了,没有一直调用setData吧
      2020-03-16
      回复
    • 我现在只想好好睡一觉
      我现在只想好好睡一觉
      2020-03-16回复我现在只想好好睡一觉
      貌似小程序现在支持position: sticky了,可以试试这个吧
      2020-03-16
      回复
    • 111
      111
      2020-03-16回复我现在只想好好睡一觉
      position: sticky 只适合极其简单的布局  复杂一点的布局或者需要在固定时还触发事件的需求完全没有用
      2020-03-16
      回复
    • 111
      111
      2020-03-16回复我现在只想好好睡一觉
      因为只要滚动都触发onPageScroll函数 你的else判断里的东西也执行啊 基础过关了吗
      2020-03-16
      回复
    查看更多(2)
  • 珱㻏
    珱㻏
    2020-06-20

    请问,动态数据,使用wx.createIntersectionObserve()好像是不行的吧

    2020-06-20
    赞同
    回复
  • 一骑白马开吴疆🐎
    一骑白马开吴疆🐎
    2020-06-15

    底部弹出式可试一试这个组件https://github.com/MakerGYT/mini-menu

    2020-06-15
    赞同
    回复
  • 刘员外
    刘员外
    2020-01-07

    滚动速度太快的话,就不会吸顶了,直接就上去了

    2020-01-07
    赞同
    回复 1
    • 111
      111
      2020-01-08
      机子性能不一样 兼容性太差了 不用这种方法直接全部setData又一直卡
      2020-01-08
      回复
  • 冰是沉默的水
    冰是沉默的水
    2019-11-20

    不知道这个怎么样,没来得及在小程序上试试

    https://www.runoob.com/try/try.php?filename=trycss_position_sticky

    2019-11-20
    赞同
    回复
  • 27
    27
    2019-09-05

    在开发者工具上,快速滚动,吸顶会失效。

    2019-09-05
    赞同
    回复 2
    • 111
      111
      2019-09-05
      思路是这样,但是具体自己调节参照区域以及滚动触发的scrollTop值
      2019-09-05
      回复
    • 27
      27
      2019-09-05回复111
      谢谢
      2019-09-05
      回复
  • 浊
    2019-08-19

    这个好像有些问题吧,有的时候滚得快一点他就不会吸顶直接过去了

    2019-08-19
    赞同
    回复 2
    • 111
      111
      2019-08-19
      调试一下自定义参照区域的高度
      2019-08-19
      回复
    • 浊
      2019-08-19回复111
      好的,我等下试试
      2019-08-19
      回复
  • 阿白
    阿白
    2019-08-14

    大神 最好提供个代码片段 学习一下 谢谢

    2019-08-14
    赞同
    回复 1
    • 111
      111
      2019-08-14
      我感觉说的蛮细的啊... 上面的js整到一个Page方法里不就行了嘛,我也小白的
      2019-08-14
      回复
登录 后发表内容