uiapp tab栏切换时内容自动滚动到相对应的位置
业务需求1,tab栏的项是动态的,可横向滚动,2,点击tab栏时,内容自动滚到相对应的位置3,滚动内容时,对应的内容要高亮对应的tab视频展示下面介绍代码(都带有注释就不一一介绍)<template><scroll-view class="tab-scroll-sticky" id="tabs" scroll-y="true" @scroll="tabScoll" :scroll
·
业务需求
1,tab栏的项是动态的,可横向滚动,
2,点击tab栏时,内容自动滚到相对应的位置
3,滚动内容时,对应的内容要高亮对应的tab
视频展示
下面介绍代码(都带有注释就不一一介绍)
<template>
<scroll-view class="tab-scroll-sticky" id="tabs" scroll-y="true" @scroll="tabScoll" :scroll-top="scrollInto">
<view class="directSignature">
<view id="scrollTop">
<!-- 顶部信息 -->
<view class="directSignature-top">
头部
</view>
</view>
<view class="scroll-content">
<view :class="[barshow?'scroll-tab-fixed':'scroll-tab-static']" :style="{top:barshow?'0':'0'}">
<scroll-view scroll-x="true" :scroll-left="scrollLeft"
style="background-color: #fff;">
<view class="scroll-tab">
<view class="scroll-tab-list" v-for="(item,index) in tabList"
:style="{color:activeTab == index?activeColor:'#8895ac'}" @click="changeTab(index)"
:id="'tabs'+index" :key="index">
<text class="scroll-tab-list-text">{{item.text}}</text>
<view v-if="activeTab == index" class="scroll-tab-list-text-line"
:style="[tabBarStyle]">
</view>
</view>
</view>
</scroll-view>
</view>
</view>
<view class="scroll-warp" ref="scroll">
<view class="scroll-warp-list" :ref="'wrap'+index" v-for="(item,index) in tabList" :key="">
<view class="directSignature-conten">
<!-- tab栏标签 -->
<view class="directSignature-tabstatus" :id="'wrap'+index">
{{item.text}}
</view>
<!-- 检查项目 -->
<view class="directSignature-checkProject">
<!-- 登记事项检查 -->
<view class="directSignature-checkProject-title" v-for="(i,index) in item.des" :key="index">
{{item.text}}---内容{{index}}
</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</template>
<script>
export default {
name: 'tab-scroll-sticky',
data() {
return {
barshow: false, //是否显示吸顶
tabTop: 0, //距离顶部的距离
activeTab: 0, //高亮tal栏的项
scrollInto: 0, //scrllo-view y轴滚动的高度
scrollLeft: 0, //tab栏X轴的滚动的距离
tabBarStyle: {}, //tab栏底部行线的样式
warpTop: [], //每一个内容开始的高度(距离顶部的高度)
// 内容
tabList: [
{id:1,text:"第1111",des:20},
{id:2,text:"第22",des:20},
{id:3,text:"第333",des:20},
{id:4,text:"第44",des:20},
{id:5,text:"第55555",des:20},
{id:6,text:"第6666",des:20},
],
activeColor: '#ff0000',//线的颜色
};
},
computed: {},
onLoad(option) {
this.resetHight()
},
watch: {},
methods: {
//数据装载完成后重新获取高度
resetHight() {
this.$nextTick(async function() {
let rect = await this.GetRect("#scrollTop"); //获取id为scrollTop的div的节点信息
this.tabTop = rect.height;
this._getTabRect(0); //获取tab栏高亮第一位的信息
this.barInit(); //获取节点的高度
});
},
//获取节点信息
GetRect(selector) {
return new Promise((resolve, reject) => {
let view = uni.createSelectorQuery().in(this)
view.select(selector).boundingClientRect(rect => {
resolve(rect)
}).exec();
})
},
//获取节点距离顶部距离
barInit: async function(index) {
this.scrollInto = 0 //初始值位0
let navTargetTop = [];
let navTargetTop1 = [];
// 遍历通过ref获取对应没有个内容开始的高度
for (let i = 0; i < this.tabList.length; i++) {
var top = this.$refs['wrap' + i][0].$el.offsetTop
navTargetTop.push(parseInt(top))
}
// 最后把每一项内容开始节点的高度数组赋值给this.warpTop
this.warpTop = navTargetTop;
},
//tab切换
changeTab(e) {
var that = this
this.activeTab = e;
this.$nextTick(function() {
that._getTabRect(that.activeTab); //页面点击切换的时候,重新设置tab栏的信息参数
if (e == 0) {
that.scrollInto = that.warpTop[e] - 44;
} else {
that.scrollInto = that.warpTop[e] - 93;
}
})
},
//获取一个tab宽度
async _getTabRect(itemIndex) {
// 获取tab栏的信息
let rect = await this.GetRect("#tabs" + itemIndex);
let rect1 = await this.GetRect("#tabs" + itemIndex + ">.scroll-tab-list-text");
let width = (rect1.width * 0.67);
if (itemIndex == this.activeTab) {
this.scrollLeft = rect.left //向做滚动的距离
}
this.tabBarStyle = {
width: width + 'px',
background: this.activeColor,
}
},
//Y轴scroll滚动
async tabScoll(e) {
let scrollTop = e.detail.scrollTop; //获取滚动的高度
let rect = await this.GetRect("#scrollTop"); //获取页面信息
// 第一次滚动时,tabTop=0
if (this.tabTop == 0) {
let rect = await this.GetRect("#scrollTop");
this.tabTop = rect.height; //页面没有距离顶部的距离
}
// this.tabTop = 0 显示置顶
this.barshow = scrollTop >= this.tabTop ? true : false;
let scrollTop1 = scrollTop;
// 循环遍历所有内容开始节点的高度数组
for (var i = 0; i < this.warpTop.length; i++) {
// 滚动的高度scrollTop1 小于this.warpTop[0],
if (scrollTop1 <= this.warpTop[0]) {
this.activeTab = 0;
this.scrollInto = this.warpTop[0] - 44 //y轴滚动回this.warpTop[0]第一个节点的位置
this._getTabRect(0);
} else if (scrollTop1 > this.warpTop[this.warpTop.length - 1] - 93) {
// 如果大于最后一位
this.activeTab = this.warpTop.length - 1;
this.scrollInto = this.warpTop[this.warpTop.length - 1]
this._getTabRect(this.warpTop.length - 1);
} else {
// 其它,同理
if (scrollTop1 > this.warpTop[i] - 93 && scrollTop1 < this.warpTop[i + 1] - 93) {
this.scrollInto = scrollTop1
this.activeTab = i;
this._getTabRect(i);
}
}
}
},
}
};
</script>
<style lang="scss" scoped>
uni-page-body{
height: 100%;
overflow: hidden;
}
.tab-scroll-sticky{
height: 100%;
}
.flexRowCc {
display: flex;
flex-direction: row;
align-items: center;
}
.scroll-content {
position: relative;
::-webkit-scrollbar {
display: none;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
color: transparent;
}
.scroll-tab {
@extend .flexRowCc;
justify-content: space-between;
width: 100%;
height: 44px;
box-sizing: border-box;
border-top: 1px solid #F1F1F1;
border-bottom: 1px solid #F1F1F1;
background: #FFFFFF;
position: relative;
z-index: 999;
// overflow-x: auto;
&-static {
position: relative !important;
}
&-fixed {
position: fixed;
top: 0px;
left: 0;
width: 100%;
z-index: 9999;
}
&-list {
text-align: center;
font-size: 24upx;
color: #2266BC;
flex: 1 1 auto;
padding: 0 10upx;
position: relative;
&-text {
display: inline-block;
&-line {
position: absolute;
height: 4upx;
transform: translateX(-50%);
left: 50%;
border-radius: 16upx;
transition-duration: .5s;
margin-top: 4rpx;
}
}
}
}
}
.scroll-warp {
height: 100vh;
padding-bottom: 200upx;
// margin-bottom: 200upx;
}
// ---------------------------------------------
.directSignature {
&-top {
width: 750upx;
background: #f3c55c;
height: 500upx;
padding: 21upx;
}
&-tabstatus{
background-image: linear-gradient(to left, #f97e36, #f3c55c);
padding:10upx 30upx;
display: inline-block;
margin: 20upx 0;
color: #FFFFFF;
border-radius: 0 30upx 30upx 0;
}
&-checkProject {
padding: 0 20upx;
}
}
// 检查项目
.directSignature-checkProject {
&-title {
color: #2266bc;
font-size: 30upx;
font-weight: 550;
// background-image: linear-gradient(to bottom, #e3edf9, #fff);
padding: 20upx;
border-radius: 15upx;
border-bottom: 3upx solid #eff5fb;
white-space: 4upx;
margin-bottom: 7upx;
background-color: #e3edf9;
}
}
</style>
都看这里了,点个赞再走呗
更多推荐
已为社区贡献2条内容
所有评论(0)