微信小程序的顶部导航,点击滑动到页面对应区域

问题:制作微信小程序的头部导航,点击导航就滑动到相应的标记区,随着页面的滑动,自动切换高亮显示所做导航。

在这里插入图片描述

方案:

  1. 点击导航滑动到标记点
  2. 计算屏幕所在导航区域
  3. 注意事项
1. 点击导航滑动到标记点

页面最顶端节点(放在页面最前面),用于计算页面离屏幕的高度

<view id='top'></view>

导航节点

<view class="tab" style="opacity: {
    
    {
    
    -scrollTop/200}}" id='tab'>
    <view wx:for='{
    
    {
    
    tab}}' 
      wx:key='index'
      class="tab-item {
    
    {
    
    currentTab==index?'active':''}}"
      data-current="{
    
    {
    
    index}}"
      bindtap="tabChange">
      {
    
    {
    
    item}}
    </view>
</view>

导航数据:

tab: ['商品','店铺','评价','详情']

导航样式:

.tab {
    
    
    position: fixed;
    top: 0;
    z-index: 9;
    width: calc(100% - 160rpx);
    padding: 0 80rpx;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: #fff;
    opacity: 0;
}
.tab-item {
    
    
    height: 64rpx;
    line-height: 64rpx;
    font-size: 28rpx;
    color: #999;
    text-align: center;
   	border-bottom: 6rpx solid #fff;
}

.active {
    
    
    color:  #56ab2f;
    border-bottom: 6rpx solid #a8e063;
    transition: width 0.4s;
}

页面滑动监听

// 页面滑动监听/导航滑动监听
onPageScroll: function (e) {
    
    
  this.getTopHeight();
  this.scrollSetTab();
  if (!navHeight) this.getNavHeight();
},

计算“页面”顶端到“手机屏幕”顶端的距离,rect.top 为标记点到手机屏幕顶部的距离,超出(滑过)为负数

// 头部的距离
getTopHeight() {
    
    
  let query = wx.createSelectorQuery();
  query.select('#top').boundingClientRect((rect) => {
    
    
    this.setData({
    
    
      scrollTop: rect.top
    })
  }).exec()
},

计算导航条的高度

let navHeight = 0;
Page({
    
    
	...
})
// 获取导航条的高度
getNavHeight() {
    
    
  let query = wx.createSelectorQuery();
  query.select('#tab').boundingClientRect((rect) => {
    
    
    navHeight = rect.height + 10;
  }).exec()
},

滑动到页面某个点的高度height, 页面顶端到屏幕顶端的距离 + 标记点到屏幕顶端的距离

wx.pageScrollTo({
    
    
  scrollTop: height
  duration: 0
});
滑动到标记点

标记点为对应的导航的索引,通过导航索引定位到所做区域

<view id='point0'></view>
<view id='point1'></view>
<view id='point2'></view>
<view id='point3'></view>

点击导航滑动到标记点

// 导航切换
tabChange(e) {
    
    
  let index = e.target.dataset.current;
  this.setScrollTop(index);
  this.setData({
    
    
    currentTab: index
  })
},

页面所在的高度height = 页面顶端top高度 + 标记点rect.top的高度

// 滑动到某处 页面顶端top高度 + 标记点rect.top的高度 = 所在的高度,navHight为导航条的高度
setScrollTop(index) {
    
    
  let query = wx.createSelectorQuery();
  query.select(`#point${
      
      index}`).boundingClientRect((rect) => {
    
    
    let scrollTop = this.data.scrollTop;
    wx.pageScrollTo({
    
    
      scrollTop: rect.top - scrollTop - navHeight,
      duration: 0
    });
  }).exec()
},
2. 计算屏幕所在的导航区域

页面滑动所做区域检测

1.rect.top<=0 (0屏幕顶端位置) 标记点到导航的位置

2.rect.top>= - rect.height , 当rect.top +rect.height >= 0 时 为导航条在模块区域内

// 页面滑动时设置导航, index为检测模块标记点,标记点移动
scrollSetTab(index) {
    
    
  let query = wx.createSelectorQuery();
  let index = this.data.currentTab;
  query.select(`#point${
      
      index}`).boundingClientRect((rect) => {
    
    
    if (rect.top > navHeight) {
    
    
      console.log(index,'未到标记区')
      this.setData({
    
    
        currentTab: index -1
      })
      this.scrollSetTab();
    }
    if (-rect.top+navHeight > rect.height) {
    
    
      console.log(index,'超越标记区')
      this.setData({
    
    
        currentTab: index+1
      })
      this.scrollSetTab();
    }
  }).exec()
3. 注意事项 ⚠️

1.标记点的ID不可为数字,可以加固定的字符串, 这里使用point+导航索引做ID,以对应导航所做的区域

<view id='point0'></view>
<view id='nav'></view>

2.所有标记点应连续,不应有部分节点隔离,不然在页面滑动到非标记区时无法判断所做区域,导致导航高亮失效

3.页面滑动检测所在区域问题,检测所在导航区域是否在当前页面,如未到当前标记区,则标记点上移,如超越标记区,这导航检测下移。如滑动到非标记区,或是两个标记区存在大面积非标记区,这里将无法检测页面,导致导航高亮失效!!!

猜你喜欢

转载自blog.csdn.net/qq_1296888290/article/details/112189943