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

2,138 阅读2分钟

使用的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
        })
      }
    }
    // 隐藏吸顶头部
  },

代码片段: developers.weixin.qq.com/s/oUhsfCmP7…