思路:运用uniapp原生提供方法uni.createSelectorQuery()获取滚动对应节点的信息,即节点距离页面顶部的距离,再通过uniapp原生监听页面滚动事件onPageScroll,获取页面内容滚动的高度,二者相加即定位到对应节点的滚动距离。
1.template结构
javascript
<view class="content-tabs-box">
<view class="content-tabs" :class="{'is-fixed': isTabFixed}">
<view
v-for="(item, index) in detailTabs" :key="index"
class="tab" :class="{'active': curTab === index}" @click="scrollTo(index, item.className)">
{{item.name}}
</view>
</view>
</view>
<!-- 正文详情 -->
<view class="library-detail-content">
<view v-if="libraryDetail.videoUrl" class="content-msg">
<video :src="libraryDetail.videoUrl" autoplay style="width: 100%;" />
</view>
<view v-else class="content-msg" v-html="libraryDetail.content"></view>
</view>
<!-- 相关附件 -->
<view v-if="attachment.length > 0" class="library-detail-attachment">
<view class="attachment-box">
<view class="title">相关附件</view>
</view>
<view class="attachment-list-box">
<view v-for="(item, index) in attachment" :key="index" class="attchment-list">
<view class="list-name">{{ item.name }}</view>
<view class="download-btn" @click="download(item.url)">
<image src="@/static/images/allPolicy/download-btn.png" style="width: 35rpx;height: 36rpx;margin-right: 10rpx;" mode="scaleToFill" />
<view>下载</view>
</view>
</view>
</view>
</view>
<!-- 图文解读 -->
<view v-if="relatedPosts.length > 0" class="library-detail-relatedPosts">
<view class="attachment-box">
<view class="title">图文解读</view>
</view>
<view class="attachment-list-box">
<view v-for="(item, index) in relatedPosts" :key="index" @click="toWebView(item.url, item.title)" class="attchment-list">
<view><span style="margin-right: 20rpx;">{{ postType(item.related_classify) }}</span> {{ item.title }}</view>
</view>
</view>
</view>
2.定义变量
javascript
data() {
return {
curTab: 0,
isTabFixed: false,
tabTop: 0, // tab距离顶部的距离
curClassName: '',
pageScrollTop: 0
}
},
computed() {
detailTabs() {
let tabs = [{
name: '正文详情',
className: '.library-detail-content'
}]
if(this.attachment && this.attachment.length > 0) {
tabs.splice(1, 0, {
name: '相关附件',
className: '.library-detail-attachment'
})
}
if(this.relatedPosts && this.relatedPosts.length > 0) {
tabs.splice(2, 0, {
name: '图文解读',
className: '.library-detail-relatedPosts'
})
}
return tabs
},
}
3.方法定义
javascript
// 点击tab滚动事件
scrollTo(tab, className) {
if(!className) return
if(this.curClassName == className) return
this.curTab = tab
const query = uni.createSelectorQuery().in(this);
query.select(className).boundingClientRect(data => {
uni.pageScrollTo({
scrollTop: className == '.library-detail-content' ? 0 : (data?.top + ((this.pageScrollTop || 0))),
duration: 300
})
}).exec();
this.curClassName = className
},
// uni页面滚动监听事件
onPageScroll(e) {
// 获取tabs的距离顶部的距离
this.tabTop = uni.createSelectorQuery().select('.content-tabs').boundingClientRect(data => {
this.tabTop = data.top;
this.isTabFixed = (e.scrollTop > this.tabTop)
this.pageScrollTop = e.scrollTop
}).exec();
},