先看代码,复制使用即可,这是纵向滑动屏幕导航栏跟随滑动的效果,是一个最基础的判断滚动距离和元素距离顶部高度的方式构成的,您将看到以下效果。

滚动切换tab

以下是代码 复制粘贴即可 , 这是一个非常基础的原理,我并未进行封装或更高深的写法,为了方便您理解(尤其是作为新手,主要给您提供思路),同时并未借助框架或别的,拿来即用。部分思路我将放在注释中。

<template>
	<view class="ComBox">
		<view class="box">
			站位
		</view>
		<view class="istab" id="istab1">  <!-- 这里用来 position: sticky 来达到吸顶效果, -->
			<!-- 这里是头部tab  我写了很高 方便您预留空间以作修改 -->
			<view class="item" :class="index==1?'somitem':''" @click="Change(1)">评论</view>
			<view class="item" :class="index==2?'somitem':''" @click="Change(2)">详情</view>
			<view class="item" :class="index==3?'somitem':''" @click="Change(3)">图文</view>
		</view>
		<view class="son1" id="son01">
			<!-- 根据id 选择dom 获取其位置信息 -->
			评论
		</view>
		<view class="son2" id="son02">
			详情
		</view>
		<view class="son3" id="son03">
			图文
		</view>
		<view class="box">
			站位
		</view>
		<view class="box">
			站位
		</view>
		<view class="box">
			站位
		</view>
		<view class="box">
			站位
		</view>
		<view class="box">
			站位
		</view>
		<view class="box">
			站位
		</view>
		<view class="box">
			站位
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				index: 0,
				index1: 0,   //tab的高度
				index2: 0,   //第二个子元素的top
				index3: 0,   //第二个子元素的top
				IsShow: true,  //用来阻止滚动产生的bug
			};
		},
		methods: {
			Change(index) {
				this.index = index
				this.IsShow = false //在点击事件中  页面滚动依然会触发滚动事件  因而用这个值进行限制
				if (index == 1) {
					wx.pageScrollTo({   //页面滚动行为
						scrollTop: this.index1,
						duration: 300
					});
					setTimeout(() => {
						this.IsShow = true
					}, 300)  //时间同页面滚动行为时间一样
				} else if (index == 2) {
					wx.pageScrollTo({
						scrollTop: this.index2,
						duration: 300
					});
					setTimeout(() => {
						this.IsShow = true
					}, 300)
				} else if (index == 3) {
					wx.pageScrollTo({
						scrollTop: this.index3,
						duration: 300
					});
					setTimeout(() => {
						this.IsShow = true
					}, 300)
				} else {
					let top = res[0].height
					wx.pageScrollTo({
						scrollTop: top,
						duration: 300
					});
					setTimeout(() => {
						this.IsShow = true
					}, 300)
				}
			},
			getDefault() {
				const query = wx.createSelectorQuery()
				query.select('#istab1').boundingClientRect()   //获取要操作的元素
				query.select('#son01').boundingClientRect()
				query.select('#son02').boundingClientRect()
				query.select('#son03').boundingClientRect()
				query.exec((res) => {
					this.index1 = res[0].height
					this.index2 = res[2].top - res[0].height + 1
					this.index3 = res[3].top - res[0].height + 1
				})
			},
			getTop(index) {
				const query = wx.createSelectorQuery()
				query.select('#istab1').boundingClientRect()
				query.select('#son01').boundingClientRect()
				query.select('#son02').boundingClientRect()
				query.select('#son03').boundingClientRect()
				query.exec((res) => {
					if (res[0].top == 0 && res[1].top <= res[0].height && res[1].bottom >= res[0].height) {   //判断 
						this.index = 1
					} else if (res[0].top == 0 && res[1].bottom <= res[0].height && res[2].bottom >= res[0].height) {
						this.index = 2
					} else if (res[0].top == 0 && res[2].bottom <= res[0].height && res[3].bottom >= res[0].height) {
						this.index = 3   
						//如果您需要更多的页面 则这样添加即可   记得在上面获取 以及在初始化时也获取
						// else if (res[0].top == 0 && res[3].bottom <= res[0].height && res[4].bottom >= res[0].height) {
						// 	this.index = 4 
						// }
					} else {
						this.index = 0
					}
				})
			}
		},
		onPageScroll(e) {
			this.IsShow ? this.getTop() : ''
		},
		onLoad() {
			this.getDefault()  //获取初始化的位置高度
		}
	};
</script>

<style lang="scss" scoped>
	.ComBox {
		height: auto;
		position: relative;
		.box {
			height: 200rpx;
			background: #f7f7f7;
			border: 1rpx solid skyblue;
			box-sizing: border-box;
			text-align: center;
			line-height: 200rpx;
		}
		.istab {
			height: 200rpx;
			position: sticky !important;
			text-align: center;
			line-height: 200rpx;
			z-index: 999;
			top: 0;
			display: flex;
			justify-content: space-between;
			background: #fff;
			.item {
				width: 25%;
				background: #f7f7f7;
			}
			.somitem {
				color:red;
				font-size:40rpx;
			}
		}
		.son1 {
			height: 600rpx;
			background: red;
		}
		.son2 {
			height: 800rpx;
			background: yellow;
		}
		.son3 {
			height: 500rpx;
			background: red;
		}
	}
</style>

其他有关uniapp的疑问或者此方法不理解的地方您可留言,我会尽快回复并帮您解决。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐