template
<view class="sticky-container u-m-b-20" :class="{ 'sticky-container--hidden': isNavHidden }" :style="{ transform: isNavHidden ? `translateY(-${stickyContainerHeight}rpx)` : 'translateY(0)' }">
<ld-custom-tabs
class="shop-type-tabs"
:list="shopTypeTabs"
:current="activeShopTab"
@change="handleShopTabChange"
/>
</view>
<!-- 篩選條件:累計(jì)直推獎(jiǎng)勵(lì)、上月直推獎(jiǎng)勵(lì)、本月直推獎(jiǎng)勵(lì) -->
<view class="filter-tabs-sticky" :class="{ 'filter-tabs-sticky--hidden': isNavHidden }" :style="{ top: stickyContainerHeight + 'rpx', transform: isNavHidden ? `translateY(-${stickyContainerHeight}rpx)` : 'translateY(0)' }">
<ld-filter-tabs
class="filter-tabs"
:list="filterTabs"
:current="activeFilterIndex"
:item-style="{ backgroundColor: '#fff', border: '1rpx solid #e5e5e5' }"
@change="handleFilterChange"
@reclick="handleFilterReclick"
/>
</view>
data
loading: false,
// sticky-container 的高度,用于設(shè)置 filter-tabs-sticky 的 top 值
stickyContainerHeight: 0, // 默認(rèn)值 0rpx
// filter-tabs-sticky 距離頂部的距離(rpx)
filterTabsStickyTop: 0,
// 是否隱藏導(dǎo)航(向上移動(dòng))
isNavHidden: false,
// 上次滾動(dòng)位置,用于判斷滾動(dòng)方向
lastScrollTop: 0
onReady() {
this.$nextTick(() => {
this.updateFilterTabsStickyPosition()
})
},
onPageScroll(e) {
this.handlePageScroll(e.scrollTop || 0)
},
methods
// 查詢?cè)爻叽缧畔? queryRect(selector) {
return new Promise(resolve => {
uni.createSelectorQuery()
.in(this)
.select(selector)
.boundingClientRect(rect => {
resolve(rect)
})
.exec()
})
},
// 更新 filter-tabs-sticky 的 top 值
async updateFilterTabsStickyPosition() {
const systemInfo = uni.getSystemInfoSync()
const pxToRpxRatio = 750 / systemInfo.windowWidth
// 獲取 sticky-container 的高度
const stickyRect = await this.queryRect('.sticky-container')
if (stickyRect && stickyRect.height) {
this.stickyContainerHeight = stickyRect.height * pxToRpxRatio
}
// 獲取 filter-tabs-sticky 距離頂部的距離
// 在 onReady 時(shí),頁(yè)面應(yīng)該還沒(méi)有滾動(dòng),所以 top 就是相對(duì)于頁(yè)面頂部的位置
const filterTabsRect = await this.queryRect('.filter-tabs-sticky')
if (filterTabsRect && filterTabsRect.top !== undefined) {
// top 是相對(duì)于視口的位置,在初始狀態(tài)下(scrollTop = 0)就是相對(duì)于頁(yè)面頂部的位置
this.filterTabsStickyTop = filterTabsRect.top * pxToRpxRatio
}
},
// 處理頁(yè)面滾動(dòng)
handlePageScroll(scrollTop) {
if (!this.stickyContainerHeight || !this.filterTabsStickyTop) return
// 將 scrollTop (px) 轉(zhuǎn)換為 rpx
const systemInfo = uni.getSystemInfoSync()
const pxToRpxRatio = 750 / systemInfo.windowWidth
const scrollTopRpx = scrollTop * pxToRpxRatio
// 計(jì)算滾動(dòng)閾值:filter-tabs-sticky 距離頂部的距離 - stickyContainerHeight
const threshold = this.filterTabsStickyTop - this.stickyContainerHeight
// 判斷滾動(dòng)方向
const isScrollingUp = scrollTop > this.lastScrollTop
const isScrollingDown = scrollTop < this.lastScrollTop
// 更新上次滾動(dòng)位置
this.lastScrollTop = scrollTop
// 判斷是否需要隱藏導(dǎo)航
if (scrollTopRpx >= threshold) {
// 超過(guò)閾值,根據(jù)滾動(dòng)方向決定是否隱藏
if (isScrollingUp) {
// 向上滾動(dòng),隱藏導(dǎo)航
this.isNavHidden = true
} else if (isScrollingDown) {
// 向下滾動(dòng),顯示導(dǎo)航
this.isNavHidden = false
}
// 如果滾動(dòng)方向不變,保持當(dāng)前狀態(tài)
} else {
// 未超過(guò)閾值,顯示導(dǎo)航
this.isNavHidden = false
}
}
},
css
.sticky-container {
position: sticky;
top: 0;
left: 0;
right: 0;
z-index: 10;
background-color: #f5f6fa;
padding: 12rpx 0;
margin: 0 -24rpx 16rpx;
transition: transform 0.3s ease-out;
}
.filter-tabs-sticky {
position: sticky;
left: 0;
z-index: 9;
background-color: #f5f6fa;
padding: 12rpx 0;
margin: 0 -24rpx 16rpx;
transition: transform 0.3s ease-out;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。