小程序導航欄懸浮、切換導航欄滾動頁面、滾動頁面切換導航欄


前言


 很多小程序、app都有這種設計:

效果1.將導航欄固定在頁面頂部。

效果2.點擊導航欄,頁面自動滾動到對應內容位置。

效果3.滾動頁面自動切換至對應導航欄

效果演示:

代碼

wxml

<!-- 導航欄 -->
<view class="topView">
  <scroll-view class="tabs" scroll-x="true" scroll-with-animation='true' scroll-into-view="x{{xId}}">
    <view class="tab {{xId==item.id?'greenColor':''}}" wx:for="{{list}}" wx:key="item" data-id="{{item.id}}"
      catchtap="changeTab" id="x{{item.id}}">
      <view class="tab_text">{{item.title}}</view>
      <view class="tab_line {{xId==item.id?'greenBg':''}}"></view>
    </view>
  </scroll-view>
</view>

<view style="height:80rpx"></view>

<!-- 滾動內容 --> <scroll-view class="columns" scroll-y="true" scroll-with-animation='true' scroll-into-view="f{{yId}}" style='height:{{height}}rpx;' bindscroll="scrollFloor"> <view class="column " wx:for="{{list}}" wx:key="item" id="f{{item.id}}"> <view class="column_title">{{item.title}}</view> <view class="column_imgs"> <view class="img_div" wx:for="{{item.photo}}" wx:for-item="items" wx:key="items"> <image src="{{items}}" mode="aspectFill"></image> </view> <view class="img_div" wx:if="{{item.photo.length>7}}"> <view class="showMore">點擊查看更多</view> </view> </view> </view> <view style="height:200rpx"></view> </scroll-view>

屬性解釋:

scroll-x="true": 允許橫向滾動,反之 scroll-y="true" 允許縱向滾動。

scroll-with-animation:在設置滾動條位置時是否使用動畫過渡。

scroll-into-view:滾動到哪個元素(值應為某子元素id【id不能以數字開頭】,例如本文的:id="x{{item.id}}" 或 id="f{{item.id}}" 設置哪個方向可滾動,則在哪個方向滾動到該元素)。

bindscroll:內容滾動時觸發的事件。

wxss

.greenColor {
  color: rgb(59 185 80);
}

.greenBg {
  background-color: rgb(59 185 80);
}

.topView {
  position: fixed;
  top:0rpx;
  left:0rpx;
  z-index:999;
  width:100%;
  background-color: #fff;
  height: 80rpx;
}

/* 導航tab */
.tabs {
  white-space: nowrap;
  padding-left: 32rpx;
  width: 100%;
  overflow: hidden;
}

/* 隱藏scroll-view頁面滾動條 */
::webkit-scrollbar {
  width: 0;
  height: 0;
  color: #fff;
  display: none;
}

.tabs .tab {
  display: inline-block;
  padding-right: 50rpx;
}

.tab_text {
  height: 50rpx;
  line-height: 50rpx;
  padding-bottom: 10rpx;
}

.tab_line {
  margin: 0 auto;
  width: 30rpx;
  height: 5rpx;
}
/*滾動內容*/ .column { width: 100%; box-sizing: border-box; overflow: hidden; } .column .column_title { padding: 40rpx 32rpx 0rpx 32rpx; } .column .column_imgs { padding: 0 28rpx; overflow: hidden; margin-top: 15rpx; } .column_imgs .img_div { width: 230rpx; height: 190rpx; padding: 7rpx 7rpx; box-sizing: border-box; float: left; display: -webkit-flex; -webkit-flex-wrap: nowrap; flex-wrap: nowrap; } .column_imgs .img_div image { width: 100%; height: 100%; background: #b5b5b5; } .column_imgs .img_div .showMore { width: 100%; height: 100%; background: #f3f5f8; line-height: 190rpx; text-align: center; font-size: 28rpx; color: #0f0d6b; }

js

Page({
  data: {
    height: 0,         //頁面高度 rpx
    ratio: 0,          //rpx,px轉化比
    xId: 1,           //x軸選中項
    yId: 1,           //y軸滾動位置
    heightArray: [],
    list: [{
        id: 1,
        title: "特色",
        photo: [
          "圖片url",
          "圖片url",
          "圖片url"        ],
      },
      {
        id: 2,
        title: "樓盤",
        photo: [
          "圖片url",
          "圖片url"
        ],
      },
      {
        id: 3,
        title: "樣板房",
        photo: [
          "圖片url",
          "圖片url"
        ],
      },
      {
        id: 4,
        title: "周邊配套",
        photo: [
          "圖片url",
          ""
        ],
      },
      {
        id: 5,
        title: "售樓處",
        photo: [
          "圖片url",
          "圖片url"
        ],
      },
      {
        id: 6,
        title: "樓盤證件",
        photo: [
          "t圖片url",
          "圖片url"
        ],
      },
    ]
  },

  onLoad: function (options) {
    let that = this
    wx.setNavigationBarTitle({
      title: '相冊頁'
    })
    //1. 獲取頁面高度
    wx.getSystemInfo({
      success: function (res) {
        let width = res.windowWidth
        let ratio = 750 / width
        let height = ratio * res.windowHeight
        that.setData({
          height: height, //單位rpx
          ratio: ratio
        })
      }
    })
  },

  onShow: function () {
    let that = this,
      heightArray = [];
    //1.獲取滾動元素距離頂部位置-y
    setTimeout(function () {
      let query = wx.createSelectorQuery() //創建節點查詢器
      query.selectAll('.column').boundingClientRect(function (rect) {
        rect.forEach(function (value) {
          heightArray.push((value.top - (170 / that.data.ratio)))
        })
        that.setData({
          heightArray
        })
      }).exec()
    }, 1000) //此處最好用延時,否則獲取的結果有可能是null,也有可能值不准確。 
  },
//切換tab導航欄
  changeTab: function (e) {
    let that = this
    let id = e.currentTarget.dataset.id
    that.setData({
      xId:id,
      yId:id,
    })
  },

  //監聽滾動 切換tab
  scrollFloor: function (e) {
    var that = this
    var scrollTop = e.detail.scrollTop //滾動條距離頂部
    var heightArray = that.data.heightArray //滾動項距離頂部
    var id = null
    //計算比較得出下標
    for (let i = 0; i <= heightArray.length; i++) {
      if (scrollTop >= heightArray[i] - 90 && scrollTop < heightArray[i + 1]) {
//-90:因為tab導航欄本身占一定高度,所以要減去tab導航欄的高度,數據可根據自身情況進行修改 id
= that.data.list[i].id } } that.setData({ xId: id }) }, })

思路

效果1 導航欄懸浮:

父盒子class="topView" 包裹scroll-view 導航欄,父盒子樣式屬性

.topView {
  position: fixed;
  top:0rpx;
  left:0rpx;
  z-index:999;
  width:100%;
  background-color: #fff;
  height: 80rpx;
}

注意:

1.z-index提高層級,避免被滾動內容覆蓋。

2.寬度一定要設置,不然會頂部tab欄將無法左右滑動。

3.scroll-view 組件使用:white-space: nowrap;overflow: hidden; 並且其子元素設置 :display: inline-block;

 

效果2  點擊導航欄,頁面自動滾動到對應內容位置:

 導航欄綁定點擊事件changeTab,並通過data-id把當前tab的元素的id值傳給事件,改變xId(導航欄選中項)和yId(滾動內容選中項)的值。

 

效果3 滾動頁面自動切換至對應導航欄:

1.頁面onLoad時獲取頁面高度並賦值給 scroll-view 的 style:height樣式屬性。

2.onShow時獲取scroll-view 內子元素距離頂部距離並依次保存在heightArray數組中。

3.頁面滾動觸發scrollFloor事件,獲取scroll-view 整個滾動框距離頂部的距離scrollTop,遍歷heightArray,如果scrollTop介於heightArray[i]和heightArray[i+1]之間,則說明頁面已經滾動至i元素,把i元素的id賦值給xId。

 

小結

以上便是我對這個功能的理解跟實現方法,代碼均已給出,各位同學有疑問或者有其他解決方案,歡迎溝通探討!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM