微信小程式的頂部導航,點選滑動到頁面對應區域
阿新 • • 發佈:2021-01-05
問題:製作微信小程式的頭部導航,點選導航就滑動到相應的標記區,隨著頁面的滑動,自動切換高亮顯示所做導航。
方案:
- 點選導航滑動到標記點
- 計算螢幕所在導航區域
- 注意事項
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.頁面滑動檢測所在區域問題,檢測所在導航區域是否在當前頁面,如未到當前標記區,則標記點上移,如超越標記區,這導航檢測下移。如滑動到非標記區,或是兩個標記區存在大面積非標記區,這裡將無法檢測頁面,導致導航高亮失效!!!