vue3 锚点定位 点击滚动高亮

功能描述

点击导航跳到对应模块的起始位置,并且高亮点击的导航;
滚动到相应的模块时,对应的导航也自动高亮;

效果展示

在这里插入图片描述

注意事项

  1. 一定要明确哪个是要滚动的盒子;
  2. 滚动的高度要减去导航栏的高度;
  3. 当前在导航1,点击导航4时,会出现导航2、导航3和导航4依次高亮的现象,定义变量判断当前为点击时不监听滚动事件即可;
    isScroll.value = false

核心代码

onMounted(() => {nextTick(() => {// 监听滚动的盒子的滚动事件document.getElementById('scrollBox').addEventListener("scroll", onScroll);})
})onBeforeUnmount(() => {document.getElementById('scrollBox').removeEventListener('scroll', onScroll)
})const scrollToAnchor = (id, index) => {activeIndex.value = indexvar anchor = document.getElementById(id);var scrollBox = document.getElementById('scrollBox')nextTick(() => {scrollBox.scrollTo({top: anchor.offsetTop - 30,behavior: 'smooth'});})isScroll.value = false// 点击时暂停页面的滚动监听事件,防止点击时导航高亮出现走马灯效果;// 此处的定时器存在缺陷,点击完2秒之内滚动还是会偶现走马灯现象;let timeId = '';clearTimeout(timeId);timeId = setTimeout(() => {isScroll.value = true;}, 2000);
};// 滚动监听器
const onScroll = ()=> {if(!isScroll.value) return// 获取所有锚点元素const navContents = document.querySelectorAll('.container .section')// 所有锚点元素的 offsetTopconst offsetTopArr = []navContents.forEach(item => {offsetTopArr.push(item.offsetTop-30)})// 获取当前文档流的 scrollTopconst scrollTop = document.getElementById('scrollBox').scrollTop// 定义当前点亮的导航下标let navIndex = 1for (let n = 1; n <= offsetTopArr.length; n++) {// 如果 scrollTop 大于等于第 n 个元素的 offsetTop 则说明 n-1 的内容已经完全不可见// 那么此时导航索引就应该是 n 了if (scrollTop >= offsetTopArr[n-1]) {navIndex = n}}// 把下标赋值给 vue 的 dataactiveIndex.value = navIndex
}

完整代码

<template><div class="box" id="scrollBox" v-loading="loading"><div class="fixed-box"><div v-for="(i) in defaultTabs" :class="{active_anchor: activeIndex === i}"><a @click="scrollToAnchor(`section${i}`, i)"><span v-if="i == 1">导航1</span><span v-if="i == 2">导航2</span><span v-if="i == 3">导航3</span><span v-if="i == 4">导航4</span><span v-if="i == 5">导航5</span></a></div></div><div class="container" id="printcontent"><div class="section" id="section1"><h3>日历</h3><el-calendar v-model="value" /></div><div class="section" id="section2"><h3>带边框列表</h3><el-descriptions class="margin-top" title="" :column="4" border><template v-for="i in 4"><el-descriptions-item label="Username">kooriookami</el-descriptions-item><el-descriptions-item label="Telephone">18100000000</el-descriptions-item><el-descriptions-item label="Place" :span="2">Suzhou</el-descriptions-item><el-descriptions-item label="Remarks">123123</el-descriptions-item><el-descriptions-item label="Username">一一一</el-descriptions-item><el-descriptions-item label="Remarks">123123</el-descriptions-item><el-descriptions-item label="Remarks">-</el-descriptions-item><el-descriptions-item label="Remarks">-</el-descriptions-item><el-descriptions-item label="Remarks">-</el-descriptions-item></template></el-descriptions></div><div class="section" id="section3"><h3>普通表格</h3><el-table :data="tableData" style="width: 100%"><el-table-column prop="date" label="Date" width="180" /><el-table-column prop="name" label="Name" width="180" /><el-table-column prop="address" label="Address" /></el-table></div><div class="section" id="section4"><h3>普通卡片</h3><el-card class="box-card"><template #header><div class="card-header"><span>Card name</span><el-button class="button" text>Operation button</el-button></div></template><div v-for="o in 10" :key="o" class="text item">{{ 'List item ' + o }}</div><template #footer>Footer content</template></el-card></div></div></div>
</template><script setup>
import { onMounted, ref, nextTick, onBeforeUnmount } from 'vue'
const loading = ref(false)
const value = ref(new Date())
const defaultTabs = ref([1, 2, 3, 4, 5])
const activeIndex = ref(1)
const isScroll = ref(true) // 点击导航栏时,暂时停止监听页面滚动
const tableData = [{date: '2016-05-03',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '2016-05-02',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '2016-05-04',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '2016-05-01',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '2016-05-04',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '2016-05-01',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '2016-05-04',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '2016-05-01',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '2016-05-04',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '2016-05-01',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '2016-05-04',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},{date: '2016-05-01',name: 'Tom',address: 'No. 189, Grove St, Los Angeles',},
]onMounted(() => {nextTick(() => {document.getElementById('scrollBox').addEventListener("scroll", onScroll);})
})onBeforeUnmount(() => {document.getElementById('scrollBox').removeEventListener('scroll', onScroll)
})const scrollToAnchor = (id, index) => {activeIndex.value = indexvar anchor = document.getElementById(id);var scrollBox = document.getElementById('scrollBox')nextTick(() => {scrollBox.scrollTo({top: anchor.offsetTop - 30,behavior: 'smooth'});})// 点击时暂停页面的滚动监听事件,防止点击时导航高亮出现走马灯效果;// 此处的定时器存在缺陷,点击完2秒之内滚动还是会偶现走马灯现象;isScroll.value = falselet timeId = '';clearTimeout(timeId);timeId = setTimeout(() => {isScroll.value = true;}, 2000);
};// 滚动监听器
const onScroll = ()=> {if(!isScroll.value) return// 获取所有锚点元素const navContents = document.querySelectorAll('.container .section')// 所有锚点元素的 offsetTopconst offsetTopArr = []navContents.forEach(item => {offsetTopArr.push(item.offsetTop-30)})// 获取当前文档流的 scrollTopconst scrollTop = document.getElementById('scrollBox').scrollTop// 定义当前点亮的导航下标let navIndex = 1for (let n = 1; n <= offsetTopArr.length; n++) {// 如果 scrollTop 大于等于第 n 个元素的 offsetTop 则说明 n-1 的内容已经完全不可见// 那么此时导航索引就应该是 n 了if (scrollTop >= offsetTopArr[n-1]) {navIndex = n}}// 把下标赋值给 vue 的 dataactiveIndex.value = navIndex
}</script>
<style scoped lang="scss">
.box{// width: 98%;margin: auto;height: 100%;overflow: auto;
}
.fixed-box{width: calc(100% - 200px);background: white;position: fixed;top: 84px;display: flex;justify-content: space-between;align-items: center;z-index: 99;padding: 5px 30px;box-sizing: border-box;box-shadow: 1px 1px 1px #ccc;span {padding: 0 10px;list-style: none;}
}
.container {padding-top: 15px;position: relative;
}
.section {margin: 20px 0;
}
:deep(.el-tabs ){--el-tabs-header-height: 50px;
}
.active_anchor {color: #409eff;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/625078.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【发票识别】支持pdf、ofd、图片格式(orc、信息提取)的发票

背景 为了能够满足识别各种发票的功能&#xff0c;特地开发了当前发票识别的功能&#xff0c;当前的功能支持pdf、ofd、图片格式的发票识别&#xff0c;使用到的技术包括文本提取匹配、ocr识别和信息提取等相关的技术&#xff0c;用到机器学习和深度学习的相关技术。 体验 体…

vue知识-06

es6导入导出语法 # 做项目&#xff1a;肯定要写模块--导入使用 # 如果包下有个 index.js 直接导到index.js上一次即可 默认导出和导入 : export default name // 只导出变量 export default add // 只导出函数 export default {name,add} // 导出对象 export defau…

【Linux】Git - 新手入门

文章目录 1. git 版本控制器 - 该如何理解&#xff1f;2. git / gitee / github 区别&#xff1f;3. Linux 中 git 的使用3.1 安装 git3.2 使用 github 新建远端仓库3.2.1 账号注册3.2.2 创建代码仓库3.2.3 克隆仓库到本地3.2.4 .gitignore 文件 3.3 使用 git 提交代码到 githu…

LeetCode 0082.删除排序链表中的重复元素 II:模拟

【LetMeFly】82.删除排序链表中的重复元素 II&#xff1a;模拟 力扣题目链接&#xff1a;https://leetcode.cn/problems/remove-duplicates-from-sorted-list-ii/ 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字…

数据结构学习 jz30 包含 min 函数的栈

关键词&#xff1a;排序 题目&#xff1a;最小栈 方法一&#xff1a;在记录这个数的同时&#xff0c;记录目前的最小值。看了提示才写出来的。 方法二&#xff1a;辅助栈。辅助栈保持非严格递减。看了k神的答案。 方法一&#xff1a; 一开始没想到怎么存最小&#xff0c;看…

【野火i.MX6NULL开发板】Linux系统下的Hello World

0、前言 参考资料&#xff1a; 《野火 Linux 基础与应用开发实战指南基于 i.MX6ULL 系列》PDF 第25章 本章比较抽象&#xff0c;涉及理论知识&#xff0c;不明白&#xff0c;可以看看视频讲解&#xff1a; https://www.bilibili.com/video/BV1JK4y1t7io?p29&vd_sourcef…

拼多多今年的校招薪资。。。

拼多多校招情况分析 关于校招情况分析&#xff0c;我们写过了争议巨巨巨巨大的 华为、互联网宇宙厂 字节跳动 以及如今有点高攀不起的新能源车企 比亚迪。 群里收集过小伙伴的意见&#xff0c;除上述大厂以外&#xff0c;大家最感兴趣的还是市值刚超过阿里的砍厂&#xff1a;拼…

transbigdata笔记:其他方法

1 出租车相关 1.1 taxigps_to_od transbigdata.taxigps_to_od(data, col[VehicleNum, Stime, Lng, Lat, OpenStatus]) 输入出租车GPS数据&#xff0c;提取OD信息 data出租车GPS数据col[VehicleNum, Time, Lng, Lat, OpenStatus]五列 比如GPS数据长这样&#xff1a; oddata …

Maven《二》-- Maven的安装与配置(亲测成功版)

目录 &#x1f436;2.1 Maven的安装条件 &#x1f436;2.2 Maven安装步骤 1. 检查本地%JAVA_HOME% 2. 解压maven 3. 配置maven的环境变量 4. 校验maven是否配置成功 5. 配置本地仓库 &#x1f436;2.3 Idea配置本地Maven软件 &#x1f436;2.1 Maven的安装条件 各个工具…

为什么要找实习以及如何更好地度过实习期

前言 在职业发展的旅程中&#xff0c;实习是一个至关重要的阶段。不论是在大学生涯的尾声&#xff0c;还是在职场新人的起步阶段&#xff0c;寻找实习机会都是一项关键任务。然而&#xff0c;为什么要找实习&#xff1f;这个问题背后蕴含着更深层次的意义和价值。在这篇博客中…

java SSM物资采购管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM物资采购管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代 码和数据库&#xff0c;系统主要采…

burp靶场-API testing

burp靶场 1.服务端主题 1.API测试 https://portswigger.net/web-security/api-testing#top 1.1 api探测api路径&#xff0c;数据格式&#xff0c;交互方法&#xff0c;参数是否必选&#xff1a; ## 使用Burp Scanner来爬取 API https://portswigger.net/burp/vulnerabilit…

虚幻UE 材质-材质图层、材质图层混合

学习材质图层和材质图层混合的使用&#xff0c;便于节点扫盲。 文章目录 前言一、材质图层混合二、使用步骤总结 前言 材质混合我们之前用Bridge的插件进行混合过 而此次我们的材质混合使用UE自带的材质图层和材质图层混合来实现 一、材质图层混合 材质图层混合是一种允许将…

Github镜像加速器-FastGit

简介 FastGit 是一个对于 GitHub.com 的镜像加速器。使用共享资源为 GitHub 加速。 FastGit中文指南 # 基本使用 关于 FastGit 的使用&#xff0c;本质上与 git 有关。常规的面向 GitHub 的 clone 命令可能如下&#xff1a; git clone https://github.com/author/repo使用 F…

烟火检测/周界入侵/视频智能识别AI智能分析网关V4如何配置ONVIF摄像机接入

AI边缘计算智能分析网关V4性能高、功耗低、检测速度快&#xff0c;易安装、易维护&#xff0c;硬件内置了近40种AI算法模型&#xff0c;支持对接入的视频图像进行人、车、物、行为等实时检测分析&#xff0c;上报识别结果&#xff0c;并能进行语音告警播放。算法可按需组合、按…

《C++大学教程》4.25星号正方形

题目: //while循环实现int main() {int n;cout << "请输入边长&#xff1a;";cin >> n;int i 1; while (i < n){ // 控制行数int j 1;while (j < n){ // 控制列数if (i 1 || i n || j 1 || j n){cout << "*";}else{cout <…

yarn包管理器在添加、更新、删除模块时,在项目中是如何体现的

技术很久不用&#xff0c;就变得生疏起来。对npm深受其害&#xff0c;决定对yarn再整理一遍。 yarn包管理器 介绍安装yarn帮助信息最常用命令 介绍 yarn官网&#xff1a;https://yarn.bootcss.com&#xff0c;学任何技术的最新知识&#xff0c;都可以通过其对应的网站了解。无…

浏览器打印无法显示单选框选中效果

上面是原代码&#xff0c;我点击打印&#xff0c;出现打印页面&#xff0c;但单选框并未勾选中&#xff0c;我在外部放了一模一样的代码是能勾选上的&#xff0c;于是我对打印页的input单选框进行分析&#xff0c;发现他丢失了checked属性。然后通过gpt分析原因。得知了default…

软件测试|使用matplotlib绘制多种柱状图

简介 在数据可视化领域&#xff0c;Matplotlib是一款强大的Python库&#xff0c;它可以用于创建多种类型的图表&#xff0c;包括柱状图。本文将介绍如何使用Matplotlib创建多种不同类型的柱状图&#xff0c;并提供示例代码。 创建基本柱状图 首先&#xff0c;让我们创建一个…

【设计模式-05】Facade门面Mediator调停者 | Decorator装饰器 | Chain Of Responsibility责任链

Facade门面Mediator调停者 1、Facade门面图解 2、Mediator调停者 一般是系统内部相互交错&#xff0c;比如消息中间件(MQ)就是这种设计模式&#xff0c;对各个功能或系统之间进行解耦。 Decorator装饰器 1、问题 2、解决方案 Chain Of Responsibility责任链 一、例子场景 业…