uniapp tab内容滚动选中

在这里插入图片描述


<template>
	<view style="width: 750rpx">
		<!-- 弹出层 -->
		<u-popup :height="modelHeights" :show="modelShow" :mode="popupData.mode"  round="16"  closeable>
			
		
			<view class="u-popup-slot" :style="{
						width: ['bottom', 'top'].includes(popupData.mode) ? '550px' : '200px',
						height: ['bottom', 'top'].includes(popupData.mode) ? modelHeights : '200px',
						marginTop: ['left', 'right'].includes(popupData.mode) ? '480rpx' : '0',
					}">
					<!-- 头部 -->
					<view class="g-nav" id="g-nav">
						<view style="display: flex; justify-content: space-between; align-items: center; height: 90rpx; font-weight: 800; font-size: 30rpx">
							<view style="width: 64rpx;"></view>
							<view class="">tab内容滚动选中</view>
							<view style="padding: 5rpx 20rpx 0 0;" @click="closeModelShow">
								<image style="height: 44rpx;width: 44rpx;"/>
							</view>
						</view>
						<view class="g-nav-box">
							<!-- 分类 -->
							<span
								v-for="(item,index) in jxNav"
								:key="index"
								:class="[index==jxNavIndex?'nav-font':'']"
								@click="toAnchor"
								:data-index="index"
								:data-htmlid="item.htmlId"
							>
								{{item.name}}
							</span>
						</view>
					</view>
					<view style="height: 200rpx"></view>
			
					<!-- 具体内容 -->
					<view id="type-el" class="type-el" v-if="modelShow">
						<scroll-view
							scroll-y="true"
							:scroll-into-view="scrollIntoView"
							@scroll="scrolls"
							:style="{height:scrollViewHeight}"
							:scroll-top="scroll_top"
							:show-scrollbar="true"
						>
							<!-- style="height:900rpx;"-->
							<!-- style="height: 1900rpx;background-color: orange;"  class="scroll-view-item uni-bg-red" -->
							<view id="cp">
								<view class="tg-title">div1</view>
								<view class="" style="height: 900rpx;background-color: antiquewhite;"></view>
							</view>
							<view id="xl" class="scroll-view-item uni-bg-green">
								<view>
									<view class="tg-title">div2</view>
									<view class="" style="height: 1200rpx;background-color: antiquewhite;"></view>
								</view>
							</view>
							<view id="tg">
								<view class="tg-title">div3</view>
								<view class="" style="height: 12000rpx;background-color: antiquewhite;"></view>
							</view>
						</scroll-view>
					</view>
				</view>
				
		</u-popup>
	</view>
</template>

<script>
	import { nextTick } from 'vue';
	export default {
		
		data() {
			return {
				modelShow: true,
				popupData: {
					//弹框数据
					overlay: true,
					mode: 'bottom',
					borderRadius: '',
					closeable: true,
					closeOnClickOverlay: true,
				},
				scroll_top: 0,
				scrollViewHeight: '900rpx',
				modelHeights: '900rpx',
				// 导航
				jxNavIndex: 0, // 是第几个导航
				jxHtmlId: '',
				jxNav: [
					{ name: 'div1', htmlId: 'cp', height: 0 },
					{ name: 'div2', htmlId: 'xl', height: 0 },
					{ name: 'div3', htmlId: 'tg', height: 0 },
				],

				scrollIntoView: 'cp', // htmlId跳转到的锚点
				isScroll: true, // 判断是点击tab,还是滚动tab
				
			};
		},
		computed: {},
		created() {
			const res = uni.getSystemInfo({
				success: (res) => {
					//this.clientHeight = res.windowHeight-uni.upx2px(80)-this.getBarHeight();
					console.log(res.windowHeight);
					this.scrollViewHeight = (res.windowHeight - 200) * 2 + 'rpx';
					this.modelHeights = (res.windowHeight - 50) * 2 + 'rpx';
					console.log('this.modelHeights', this.modelHeights);
				},
			});
		},
		watch: {
			modelShow(newVal, oldVal) {
				if (newVal) {
					// 先获取高度
					this.$nextTick(() => {
						const query = uni.createSelectorQuery().in(this);
						query
							.select('#cp')
							.boundingClientRect((cp) => {
								this.jxNav[0].height = parseInt(cp.height);
							})
							.exec();
						query
							.select('#xl')
							.boundingClientRect((xl) => {
								this.jxNav[1].height = parseInt(xl.height);
							})
							.exec();
						query
							.select('#tg')
							.boundingClientRect((tg) => {
								this.jxNav[2].height = parseInt(tg.height);
							})
							.exec();
					});
				}
				
			},
		},
		mounted() {
			// 先获取高度
			this.$nextTick(() => {
				const query = uni.createSelectorQuery().in(this);
				query
					.select('#cp')
					.boundingClientRect((cp) => {
						this.jxNav[0].height = parseInt(cp.height);
					})
					.exec();
				query
					.select('#xl')
					.boundingClientRect((xl) => {
						this.jxNav[1].height = parseInt(xl.height);
					})
					.exec();
				query
					.select('#tg')
					.boundingClientRect((tg) => {
						this.jxNav[2].height = parseInt(tg.height);
					})
					.exec();
			});
		},
		methods: {
			// 关闭弹窗(修改父组件的modelShow值)
			closeModelShow() {
				this.$emit('closeModelShow', !this.modelShow);
			},
			// 滚动时,切换tab
			scrolls(e) {
				// console.log(e.detail.scrollTop) // 滚动条距离顶部的距离
				// console.log(this.jxNav)        // 保存的高度
				if (e.detail.scrollTop < this.jxNav[0].height || e.detail.scrollTop == 0) {
					this.jxNavIndex = 0;
				} else if (e.detail.scrollTop < this.jxNav[1].height + this.jxNav[0].height) {
					this.jxNavIndex = 1;
				} else if (e.detail.scrollTop < this.jxNav[2].height + this.jxNav[1].height + this.jxNav[0].height) {
					this.jxNavIndex = 2;
				}
			},
			// 顶部导航选择
			toAnchor(e) {
				let htmlid = e.currentTarget.dataset.htmlid;
				// this.scrollIntoView = htmlid
				this.jxNavIndex = e.currentTarget.dataset.index;
				// this.jxHtmlId = htmlid

				if (this.jxNavIndex == 0) {
					this.scroll_top = 0;
				} else if (this.jxNavIndex == 1) {
					this.scroll_top = this.jxNav[0].height + 5;
				} else if (this.jxNavIndex == 2) {
					this.scroll_top = this.jxNav[0].height + this.jxNav[1].height;
				}
			},
		},
	};
</script>

<style lang="scss" scoped>
	$abcd: #aa55ff;
	/* 导航 */
	.g-nav {
		position: fixed;
		z-index: 999;
		//position: sticky;
		//top: 129rpx;

		width: 750rpx;
		height: 200rpx; // 88rpx
		overflow: auto;
		background-color: #fff;
		border-bottom: 20rpx solid #f0f6f6;
		border-radius: 32rpx 32rpx 0 0;
	}
	.g-nav-box {
		display: flex;
		justify-content: space-around;

		white-space: nowrap;
		width: auto;
		// display:inline-block;
		// zoom:1
	}
	.g-nav-box span {
		/* width:140rpx; */
		padding: 0 35rpx;
		height: 88rpx;
		text-align: center;
		line-height: 88rpx;
		display: inline-block;
		font-size: 28rpx;
		color: #9a9a9a;
	}
	.nav-font {
		/* color: #014343 !important; */
		color: $abcd !important;
		font-weight: 800;
		font-size: 30rpx !important;
	}

	.type-el {
		margin: 20rpx;
		width: 710rpx;
	}
	/** div2 */
	.xl-main {
		margin: 20rpx;
		font-size: 12px;
		color: #999;
	}
	/** div3 */
	.tg-title {
		margin: 10rpx 0;
		font-size: 30rpx;
		font-weight: 800;
	}
	.tg-main {
		// border: 1rpx solid #ccc;
		.tg-main-item {
			display: flex;
			justify-content: space-between;
			align-items: center;
			height: 70rpx;
			border-bottom: 1rpx solid #ccc;
			&:last-child {
				border: 0;
			}
		}
	}
	
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值