需求:

实现滚轮滚动,左侧导航栏动态固定定位,且相应高亮对应的正文内容。

难点:

  1. 监听了scroll之后点击其他页面也会监听,会一直报错
  2. 当前页面滚轮滑到最底部后切换别的页面,也是定位在最底部,因为滚轮一直处于监听状态
  3. 固定的导航栏不能覆盖顶部信息栏和底部信息栏(动态固定)

实现:
4. 通过ref获取当前页面的scrollTop(滚动条到顶端的距离);
5. 获取需要固定定位的nav导航的父节点的高度offsetHeight(元素布局的高度)
6. 实现动态定位:如果滚动的距离大于0并且小于nav导航父节点的高度则固定定位;如果小于则取消固定定位
7. 附加需求:需要响应高亮对应滚动的小标题
8.

<template>
	<div class="mian" ref="mainRef">
		页面内容
		<div class="hardware_nav">
			//需要定位的导航栏
        	<div v-for="item in HARDWAR" :key="item.key" @click="topNav(item.key)"
          		:class="info.heightLight === item.key ? 'light' : 'no_light'">
          		<span style="margin-left: 10px;">{{ item.text }}</span>
        	</div>
      	</div>
	</div>
</template>
<script>
import { defineComponent, ref, inject, onMounted, reactive, onBeforeUnmount } from "vue";
export default defineComponent({
	setup(){
		const info = reactive({
      		heightLight: 0,//高亮的id
      		moveIndex: 0,
      		ContentHeightList: [],//每个区域距离顶部的高度数组
    	})
		const mainRef = ref({});
		const onPageSrcoll = function () {
      		const parentElement = mianRef.value.parentElement;
      		let scrollTop = 0;
      		scrollTop = parentElement.scrollTop - 300 || 0; //因为有底部高度差,对应减掉
      		let Heights = info.ContentHeightList;//每个区域距离顶部的高度数组
      		//高亮导航栏,对应滚动的区域标题
      		if (info.ContentHeightList) {
        		for (let i = 0; i <= Heights.length; i++) {
        		//如果滚动高度大于当前区域小于下一个区域 则高亮当前区域的标题
          			if (scrollTop >= Heights[i] && scrollTop <= Heights[i + 1]) {
            			info.heightLight = i;
         	 		}
        		}
      		}
      		let nav = document.querySelector(".hardware_nav")
      		let maxHeight = document.querySelector(".hardware-content").offsetHeight - 600;
      		if (scrollTop >= 0 && scrollTop <= maxHeight) {
        		nav.style.position = 'fixed'
        		nav.style.top = 10 + '%'
      		} else if (scrollTop <= maxHeight) {
        		nav.style.position = 'absolute'
        		nav.style.top = 1 + '%'
      		} else {
        		nav.style.position = 'absolute'
        		nav.style.top = 84 + '%'
      		}
    	}
    	
    	// 获取每个区域的高度数组
		function getChildrenHeigh() {
      		let pageScrooll = document.querySelector(".hardware-item").parentNode;
      		let arr = [];
      		for (let i = 1; i <= HARDWAR.length; i++) {
        		if (i == HARDWAR.length) {
          			arr.push(pageScrooll.children[i].offsetTop - 100)
        		} else {
          			arr.push(pageScrooll.children[i].offsetTop);
        		}
      		}
      		arr.push(Number.MAX_VALUE);
      		info.ContentHeightList = arr;
    	}
    	
		onMounted(() => {
      		const parentElement = mainRef.value.parentElement;
     		parentElement.addEventListener("scroll", onPageSrcoll)
    	})
    	
		return{getChildrenHeigh}
	}
})
</script>

解决:
1. 监听scroll之后点击其他页面也会监听,一直报错的问题
2.当前页面滚轮滑到最底部后切换别的页面,也是定位在最底部,因为滚轮一直处于监听状态

监听之后需要销毁scroll监听

onBeforeUnmount(() => {
	const parentElement = mainRef.value.parentElement;
	parentElement.removeEventListener("scroll", onPageSrcoll)
})
Logo

前往低代码交流专区

更多推荐