17.最近遇到了一个难点

需求描述: 一个小程序页面滚动,切换tab的需求。tab 并不是页面初始时,就固定在页面头部的,是页面滚动到某个距离时,做的吸顶效果。具体如下图:

需求描述

由于,一开始,我是根据scrollHeight 介于heightArr 哪个区间,然后判断acitveIndex 的值,结果发现超级复杂,会有很多中情况,我总不能写N多if去判断吧,且这样的做法,不方便以后拓展。


所以就换了个思路。新思路如下:

首先,初始的acitveIndex 还是根据 heightArr[i] > 0

然后,切换事件,做的事情就是如下:

/**

   * 切换tab

   */

  handleChangeSeleted(e) {

    this.setData({

      showFixedMenu: true

    }, () => {

      const id = e.target.dataset.id

      const query = wx.createSelectorQuery()

      query.select(`#${ id }`).boundingClientRect()

      query.select('#fixed').boundingClientRect()

      query.selectViewport().scrollOffset()

      query.exec(rect => {

        const outSide = rect[1] !== null ? rect[1].bottom : 0

        wx.pageScrollTo({

          scrollTop: Math.ceil(rect[0].top + this.data.scrollTop - outSide)

        })

      })

    })

  }

这里的outSide 即为固定tab 时,下边距的可视区域的距离。那么acitveIndex就根据滚动事件去设置,所以滚动事件的实现如下:

主要是作为activeIndex 界定的参照对象不再是scrollHeight,而是fixed tab的下边界,如果一个内容区域 item !== null && item.top < outSide && item.bottom >= outSide,那么当前的内容区域,即为activeIndex。

  /**

   * 页面滚动

   */

  onPageScroll(e: any) {

    // 保存当前已经滚动的距离

    this.data.scrollTop = e.scrollTop

    // 吸顶效果 start

    let showFixedMenu

    const query = wx.createSelectorQuery().select('#menu-box').boundingClientRect()

    query.exec(rect => {

      if (rect[0] === null) {

        return

      }

      const statusBarHeight = wx.getSystemInfoSync().statusBarHeight

      if (rect[0].top <= statusBarHeight) {

        showFixedMenu = true

      } else {

        showFixedMenu = false

      }

      if (showFixedMenu === this.data.showFixedMenu) {

        return

      }

      this.setData({

        showFixedMenu

      })

    })

    // 吸顶效果 end

    // 菜单选中 start

    const scrollQuery = wx.createSelectorQuery()

    scrollQuery.select('#first').boundingClientRect()

    scrollQuery.select('#second').boundingClientRect()

    scrollQuery.select('#third').boundingClientRect()

    scrollQuery.select('#fixed').boundingClientRect()

    scrollQuery.selectViewport().scrollOffset()

    scrollQuery.exec(rect => {

      const arr = [rect[0], rect[1], rect[2]]

      const selectedIndex = arr.findIndex(item => {

        const outSide = rect[3] !== null ? rect[3].bottom : 0

        return item !== null && item.top < outSide && item.bottom >= outSide

      })

      if (selectedIndex > -1) {

        this.setData({

          selectedIndex

        })

      }

    })

    // 菜单选中 end

  }

总结,说这是难点的问题在于思路,一开始思路陷进了死胡同,只想简单的根据滚动距离scrollHeihgt 介于哪两个heightArr 区间,然后取左区间的下标作为activeIndex,但是heightArr 有很多中可能性,不便计算。一时之间,也没有想到更好的方面,就在旧思路里,纠结了好几天,怎么计算啊???

突然有一天,灵光一闪,新思路就出现了!!!!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。