vue实现滚动监听,锚点定位的目录(根据文章浏览位置,目录高亮相应标题)
开开 2021-06-10 16:22:20 2021-06-10 232 0
先上效果图跟代码,然后逐步分析思路跟方法的作用
<template> <div class="container"> <div class="wrapper"> <div class="section" style="height:500px;width:100%" v-for="(item, index) in list" :key="index" :style="{'height':index==0?'1000px':'500px'}"> <div style="width:100%;height:100%;font-size:30px;text-align:center;font-weight:bold;color:#fff;" :style="{'background':item.backgroundcolor}">{{item.name}}</div> </div> </div> <div id="nac" style="height:500px;"></div> <nav style="position:fixed;right:30px;top:300px;"> <div style="margin-left:20px;font-size:16px">目录</div> <el-tabs @tab-click="handleClick" v-model="activeName" :tab-position="tabPosition" style="height: 200px;"> <el-tab-pane :name="'tab'+index" :class="index==0?'current':''" v-for="(item, index) in list" :key="index" :label="item.name"></el-tab-pane> </el-tabs> </nav> </div></template><script> export default { data(){ return { activeName:'tab0', tabPosition:'right', scroll: '', list: [{ name: "第一条", backgroundcolor: "#90B2A3" }, { name: "第二条", backgroundcolor: "#A593B2" }, { name: "第三条", backgroundcolor: "#A7B293" }, { name: "第四条", backgroundcolor: "#0F2798" }, { name: "第五条", backgroundcolor: "#0A464D" }], navList: [1, 2, 3, 4, 5] } }, methods: { //这里传入的tab相当于item handleClick(tab,event){ console.log(tab.index) this.jump(tab.index) }, dataScroll: function () { this.scroll = document.documentElement.scrollTop || document.body.scrollTop; }, jump(index) { let jump = document.getElementsByClassName('section'); // 获取需要滚动的距离 let total = jump[index].offsetTop; // Chrome document.body.scrollTop = total; // Firefox document.documentElement.scrollTop = total; // Safari window.pageYOffset = total; // $('html, body').animate({ // 'scrollTop': total // }, 400); }, // 用循环的方式将每个标题离顶部的距离与滚动条当前位置对比来确定哪个标题需要变为高亮 loadScroll: function () { var self = this; var sections = document.getElementsByClassName('section'); for (var i = sections.length - 1; i >= 0; i--) { if (self.scroll >= sections[i].offsetTop - 100) { //我在上面规定了每个el-tab-pane标签的name属性值为tab+该标签的index值 self.activeName = 'tab'+i break; } } } }, watch: { //监听scroll变量,只要滚动条位置变化就会执行方法loadScroll scroll: function () { this.loadScroll() } }, mounted() { // scroll代表滚动条距离页面顶部距离 window.addEventListener('scroll', this.dataScroll); } }</script><style lang="scss" scoped> * { padding: 0; margin: 0; } .nav1 { display: block; width: 120px; height: 40px; text-align: left; line-height: 40px; color: #fff; /* background: #eee; */ margin: 10px 0; cursor: pointer; padding-left: 18px; &:hover{ color: #0177ff; } } .current { color: #0578fc !important; cursor: pointer; } nav{ // border-left: 1px solid #eee; a{ border-left: 3px solid #0177ff; } } </style><style> .el-tabs__header.is-right{ margin-right: 100px !important; }</style>
1.点击目录上标题页面显示区域跳转到对应标题处
目录这里,图方便所以用elementui里的tabs组件做的,因为el-tab-pane这个标签上绑定方法是不出效果的,所以只能在el-tab上用官方预留的tab-click方法绑定handleClick方法,handleClick方法是为了实现鼠标点击目录时页面会显示到点击的标题位置
2.移动滚动条目录上高亮的标题也随着变化
这里是通过watch监听scroll滚动条的位置变化来实现的,每变化一次,都会执行loadScroll方法重新比对滚动条跟各标题的位置,然后更改activeName的值,从而改变目录中应该高亮的标题
3.mounted中的监听很重要,大家应该都懂,我就不说啦
参考的是一篇用jqurey实现该功能的文章,但是前两天清理了浏览记录实在找不到了,不好意思,不好意思
如果想要更实用一点的可以参考我的另一篇文章——vue.js自动提取标题生成右侧目录,效果图如下
原文: https://blog.csdn.net/weixin_46363283/article/details/107407891