vue3监听页面滚轮

需求:

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

难点:

  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)
})
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在Vue3中监听滚轮高度,你可以使用mounted钩子函数和window的scroll事件来实现。下面是一个示例代码: ```javascript data() { return { scrollHeight: 0 }; }, mounted() { window.addEventListener('scroll', this.handleScroll); }, methods: { handleScroll() { this.scrollHeight = document.documentElement.scrollTop || document.body.scrollTop; } } ``` 在这个示例中,我们通过在data中定义一个scrollHeight属性来保存滚轮的高度。在mounted钩子函数中,我们添加了一个scroll事件监听器,并将事件处理函数设置为handleScroll。在handleScroll函数中,我们使用`document.documentElement.scrollTop || document.body.scrollTop`来获取滚轮的高度,并将其赋值给scrollHeight属性。 这样,每当用户滚动页面时,handleScroll函数将被触发,scrollHeight属性将被更新为当前滚轮的高度。你可以在模板中使用这个属性来实现你需要的逻辑。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [vue3监听滚轮高度事件](https://blog.csdn.net/m0_72196169/article/details/129771890)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [VUE3 实时监听页面滚动高度 ,改变nav/title的 透明度](https://blog.csdn.net/Eternity_matt/article/details/121064416)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [vue 解除鼠标的监听事件的方法](https://download.csdn.net/download/weixin_38749268/12932141)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值