点击标题滚动到对应的 section, 滚动到对应的section 对应的标题高亮

2023-10-26

<template>
	<div class="home">
		<tab-control class="tab-control" ref="tabControl" :titles='["商品", "参数", "评论", "推荐"]' @tabClick="tabClick" />
		<scroll class="scroll" ref="scroll" :probeType="3" :pullUpLoad="true" @scroll="handleScrollContent">
			<p>联动效果:点击标题滚动到对应的 section, 滚动到对应的section 对应的标题高亮<br />点击加入购物车利用 Vuex<br />回到顶部的混入<br />111<br />111<br /></p>
			<p>111<br />111<br /></p>
			<p>111<br />111<br /></p>
			<p>111<br />111<br /></p>
			<p>111<br />111<br /></p>
			<p>111<br />111<br /></p>
			<p>111<br />111<br /></p>
			<div>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />12222<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />12222<br /></p>
				<h2 ref="tabtitle1">參數</h2>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />12222<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />12222<br /></p>
				<h2 ref="tabtitle2">評論</h2>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />12222<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />12222<br /></p>
				<h2 ref="tabtitle3">推薦</h2>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />12222<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />111<br /></p>
				<p>111<br />12222<br /></p>
			</div>
		</scroll>
	</div>
</template>
<script type="text/javascript">
import TabControl from '@/components/tabControl/TabControl'
import Scroll from '@/components/scroll/Scroll'
import BackTop from '@/components/backTop/BackTop'

export default {
	name: "Cart",
	components: { TabControl, Scroll, BackTop },
	data() {
		return {
			currentType: 0,
			anchorsTopYs: [], //得到每个 section 定位的位置

		}
	},
	mounted() {
		this.$nextTick(() => { //确保 html 都渲染完毕的时候再调用,但是图片可能依然没有加载完毕,这个操作最好在 image 加载完毕后调用,注意期间用防抖函数来降低其调用的频率
			//得到每個 section 的位置
			this.anchorsTopYs = [];
			this.anchorsTopYs.push(0);
			this.anchorsTopYs.push(this.$refs.tabtitle1.offsetTop);
			this.anchorsTopYs.push(this.$refs.tabtitle2.offsetTop);
			this.anchorsTopYs.push(this.$refs.tabtitle3.offsetTop);
			this.anchorsTopYs.push(Number.MAX_VALUE); //给它末尾加上一个最大值,方便判断
			console.log(this.anchorsTopYs);
		})

		/*注意 获取元素的 offsetTop 可能会遇到的坑
		在哪里才能获取到正确的 offfsetTop?
		1.created 肯定不行,压根通过 this.$refs 获取不到元素
		2.mounted 也不行,数据还没有获取到
		3.updated 也不行,获取到了数据 Dom 还没有渲染
		4.$nextTick 也不行,因为 dom 渲染了但是图片还没有加载完毕
		5.在图片都加载完毕后获取元素的 offsetTop, 这里注意防抖函数的应用

		普通 元素用的是 this.$refs.元素ref名.offsetTop
		组件 用的是 
		this.$refs.组件ref名.$el.offsetTop;
		*/
	},
	methods: {
		tabClick(index) { //tab 点击的时候跳转到对应 section 的位置
			this.$refs.tabControl.currentIndex = index;

			this.$refs.scroll.scrollTo(0, -this.anchorsTopYs[index]);
		},
		handleScrollContent(position) { //监听滚动位置,滚动到不同 section 高亮不同 tabtitle
			const length = this.anchorsTopYs.length;
			const y = - position.y;
			for (let i = 0; i < length - 1; i++) {
				//条件1 防止赋值的次数过于频繁 this.$refs.tabControl.currentIndex !== i
				//条件2 为了不让 i + 1 越界 i < length - 1,然后在 this.anchorsTopYs 末尾加了一个最大值 Number.MAX_VALUE
				if ((this.$refs.tabControl.currentIndex !== i) && (y >= this.anchorsTopYs[i] && y < this.anchorsTopYs[i + 1])) {
					this.$refs.tabControl.currentIndex = i;
				}
			}
		}
	},
}

</script>
<style scoped>
.home {
	height: 100vh;
	position: relative;
}

.tab-control {
	/*障眼法的 tab 的 css*/
	position: relative;
	/*设置了 position 之后才可以设置 z-index*/
	z-index: 9;
	top: 0 !important;
}

.scroll {
	background-color: red;
	position: absolute;
	left: 0;
	right: 0;
	top: 40px;
	bottom: 49px;
	overflow: hidden;
}

</style>

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

点击标题滚动到对应的 section, 滚动到对应的section 对应的标题高亮 的相关文章

随机推荐