微信小程序-锚点定位+内容滑动控制导航选中

2,925 阅读2分钟

之前两篇文章分别介绍了锚点定位和滑动内容影响导航选中,这里我们就结合起来,实现这两个功能!

思路不再多说,直接上干货!

WXML

<view class="navigateBox">
  <view class="title">
    <image wx:if="{{actionView=='productBox'}}" src="../images/position.png"/>
    <view class="title {{actionView=='productBox' ? 'checked':''}}" bindtap="toViewClick" data-hash="productBox">商品</view>
  </view>
  <view class="title">
    <image wx:if="{{actionView=='commentBox'}}" src="../images/position.png"/>
    <view class="title {{actionView=='commentBox' ? 'checked':''}}" bindtap="toViewClick" data-hash="commentBox">评价</view>
  </view>
  <view class="title">
    <image wx:if="{{actionView=='infoBox'}}" src="../images/position.png"/>
    <view class="title {{actionView=='infoBox' ? 'checked':''}}" bindtap="toViewClick" data-hash="infoBox">详情</view>
  </view>
</view>

<scroll-view style="height:{{winHeight}}" scroll-into-view="{{toView}}" scroll-y="true" bindscroll="scrollTo">
  <view id="productBox" class="content">商品信息...</view>
  <view id="commentBox" class="content">评价内容...</view>
  <view id="infoBox" class="content">商品详情...</view>
</scroll-view>

WXS

data: {
  winHeight: '100%',
  toView: 'productBox',//锚点跳转的ID
  actionView: 'productBox',//控制导航显示
  productBoxTop: 0,//商品模块距离顶部的距离
  commentBoxTop: 0,//评价模块距离顶部的距离
  infoBoxTop: 0,//详情模块距离顶部的距离
};

onLoad() {
  let that = this;
  wx.getSystemInfo({
    success: function (res) {
      //屏幕的宽度/屏幕的高度 = 微信固定宽度(750)/微信高度
      that.setData({
        winHeight = res.windowHeight-(res.windowWidth*90/750)+'px'  
      })
    }
  });
}

onShow() {
  // 获取各模块距离顶部的距离
  new Promise(resolve => {
    let query = wx.createSelectorQuery();
    query.select('#productBox').boundingClientRect();
    query.select('#commentBox').boundingClientRect();
    query.select('#infoBox').boundingClientRect();
    query.exec(function (res) {
      resolve(res);
    });
  }).then(res => {
    this.setData({
      productBoxTop: res[0].top,
      commentBoxTop: res[1].top,
      infoBoxTop: res[2].top
    });
  });
}


//锚点定位
toViewClick(e) {
  this.setData({
    toView: e.target.dataset.hash,  
    actionView: e.target.dataset.hash
  })
},

scrollTo(e){
  let scrollTop = e.detail.scrollTop+100;  //滚动的Y轴

  if(scrollTop >= this.infoBoxTop){
    this.setData({
      actionView: 'infoBox'    
    })
  }else if(scrollTop >= this.commentBoxTop){
    this.setData({
      actionView: 'commentBox'  
    })
  }else {
    this.setData({
      actionView: 'productBox'  
    })
  }

  //this.$apply();//WEPY更新数据
}

WXSS

page {
  height: 100%;
}
.navigateBox {
  background: #fff;
  height: 80rpx;
  padding: 0 100rpx;
  margin-bottom: 10rpx;
}
.navigateBox .title {
  margin: 20rpx 46rpx;
  float: left;
  font-size: 27rpx;
  width: 60rpx;
  padding-left: 30rpx;
}
.navigateBox .title .right {
  float: right;
  margin-top: -5rpx;
}
.navigateBox image {
  width: 30rpx;
  height: 30rpx;
  margin-left: -30rpx;
}
.navigateBox .checked {
  color: #f73c3c;
}
.content {
  height: 1000rpx;
}