需求背景:
PC端项目需要实现一个有侧边导航栏,可点击跳转至对应内容区域,类似锚点导航,
同时主内容区域上下滚动时,可实现左侧导航栏选中样式能实时跟随变动的效果。
了解了一下,Element Plus 组件库 和 Ant Design Vue 组件库内自带此功能组件:
Anchor 锚点 | Element Plus
Anchor 锚点 — 用于跳转到页面指定位置。
但是奈何自己的项目依旧还是 Vue2 版本的 Element 组件库,
SO,用不了,没办法只能另辟蹊径,寻找其他解决方案。
百度一波之后的参考文献:
此篇内有效果展示图:https://zhuanlan.zhihu.com/p/476337029
( 不过文章内容缺少一些代码段信息,需自行到文章下面的代码仓库查阅:
import utils from '@/utils'
import { getScrollContainer } from '@/utils/dom' )又参考了几篇文献 :
实现主内容滚动到指定位置,侧边栏也跟随变化_侧边栏滚动定位
最后采用的demo文献 :
vue实现内容滚动时,侧边导航跟随选中 - 简书
( 此篇文章代码基本都是写死的内容,不具有可变性,但是大致提供了一个思路 )
根据参考文献后改进优化后的代码 :
html 部分
<template>
<div class="container">
<ul class="nav">
<li v-for="(item, index) in domainLineList" :key="index">
<a
@click="navClick(index)"
:class="{ bbactive: selectedItem === index }"
>{{ item.deptName }}</a
>
</li>
</ul>
<article>
<h1
v-for="(item, index) in domainLineList"
:key="index"
:id="'div' + index"
>
{{ item.deptValue }}
</h1>
</article>
</div>
</template>
javascript 部分
<script>
export default {
name: "container",
data() {
return {
selectedItem: 0,
domainLineList: [
{
deptName: "奢香夫人",
deptValue: `男:落脚河上面崖对崖
威宁草海荞花盛开
谁把月亮挂天上
照得想说的话 流成海流成海
流成海流成海
女:越过绵绵的高山
越过无尽的沧海
如果期待依然在
总是春暖到花开
请你轻轻留下来
让梦卷走这尘埃
香飘在书厢之外
奏响美丽的天籁
男:不等三更过天晓白
奢香夫人赶月归来
她把日光画心上
照得漆黑的夜 亮堂堂亮堂堂
亮堂堂亮堂堂
女:越过绵绵的高山
越过无尽的沧海
如果期待依然在
总是春暖到花开
请你轻轻留下来
让梦卷走这尘埃
香飘在书厢之外
奏响美丽的天籁
合:乌蒙山连着山外山
月光洒下了响水滩
有没有人能告诉我
可是苍天对你在呼唤
一座山翻过一条河
千山万水永不寂寞
你来过 年华被传说
百里杜鹃不凋落
乌蒙山连着山外山
月光洒下了响水滩
有没有人能告诉我
可是苍天对你在呼唤
一座山翻过一条河
走过千山万水永不寂寞
你来过 年华被传说
百里杜鹃不凋落
女:怀念总在心头绕
我们记忆的凭吊
善良的心跳
男:我寻着你的路 让风都停住
依然清晰看见你那坚强的脚步
如果天留得住 如果地也能把你挽住
愿你就在这片云水间常驻
合:乌蒙山连着山外山
月光洒下了响水滩
有没有人能告诉我
可是苍天对你在呼唤
一座山翻过一条河
千山万水永不寂寞
你来过 年华被传说
百里杜鹃不凋落
乌蒙山连着山外山
月光洒下了响水滩
有没有人能告诉我
可是苍天对你在呼唤
一座山翻过一条河
走过千山万水不寂寞
你来过 年华被传说
百里杜鹃不凋落`,
},
{
deptName: "等爱的玫瑰",
deptValue: `我走在 荒凉的沙漠
我躲在 无人的角落
我听见 飘渺的传说
是谁在飞扬自由的歌
风吹过 漫天的寂寞
爱无根 枯萎的花朵
我祈祷 不变的承诺
是谁在安慰心中饥渴
我要向前飞
我是等爱的玫瑰
心中浅藏着待放的花蕊
如果你给我真实的安慰
我愿为你展现我的美
曾经被风吹
我是受伤的玫瑰
眼中深埋着滚烫的泪水
尘世中太多虚幻的安慰
完美背后看见了心碎
是谁风干的温柔
给我憧憬的理由
多少人都曾经为爱
虔诚的祈求
谁不渴望
天长地久
只怕繁华落尽
海市蜃楼
风吹过 漫天的寂寞
爱无根 枯萎的花朵
我祈祷 不变的承诺
是谁在安慰心中饥渴
又有谁从来没有受过伤害
但是我们还是要
继续找到真爱
感情复杂 难免会有失败
未来的路更值得我们期待
不要怕有我陪着你
安慰你心疼你
直到你找到爱的真谛
得到幸福的你
会明白一切付出
原来都是值得的
我要向前飞
我是等爱的玫瑰
心中浅藏着待放的花蕊
如果你给我真实的安慰
我愿为你展现我的美
曾经被风吹
我是受伤的玫瑰
眼中深埋着滚烫的泪水
尘世中太多虚幻的安慰
完美背后看见了心碎
是谁风干的温柔
给我憧憬的理由
多少人都曾经为爱
虔诚的祈求
谁不渴望
天长地久
只怕繁华落尽
海市蜃楼
我要向前飞
我是等爱的玫瑰
心中浅藏着待放的花蕊
如果你给我真实的安慰
我愿为你展现我的美
曾经被风吹
我是受伤的玫瑰
眼中深埋着滚烫的泪水
尘世中太多虚幻的安慰
完美背后看见了心碎
尘世中太多虚幻的安慰
完美背后看见了心碎`,
},
{
deptName: "冬天的秘密",
deptValue: `取暖回忆回忆无香
有阳光还感觉
我站在分隔岛
没有方向不想回
你太善良你太美
我讨厌这样想你的自
不屑此刻的我太感
与脆弱为
没有魂魄化体温成
尴尬的
始终独自怀抱这个秘
但朋友都说我太过忧
爱你我不能
看你们拥抱甜
谈笑自若忍受逾期的伤
如果我说我真的爱
谁来收
那些被破坏的友
如果我忍住这个秘
温暖冬
就会遥遥而无
你太善良你太美
我讨厌这样想你的自
不屑此刻的我太感
与脆弱为
没有魂魄化体温成
尴尬的
始终独自怀抱这个秘
但朋友都说我太过忧
爱你我不能
看你们拥抱甜
谈笑自若忍受逾期的伤
如果我说我真的爱
谁来收
那些被破坏的友
如果我忍住这个秘
温暖冬天就会遥遥而无
如果我说我必须爱
答应给
比友谊更完整的
如果我忍住这个秘
就该错过埋葬冬天的秘
如果我说我真的爱
谁来收拾这被破坏的友
如果我忍住这个秘
温暖冬天就会遥遥而无
就该错过埋葬冬天的秘密`,
},
{
deptName: "姑娘别哭泣",
deptValue: `突来的消息 那个人是你
这么多年 你杳无音讯
时间的橡皮 擦掉了记忆
但我迟迟却 没有忘记你
秒针的声音 嘀嗒转不停
我的心里 住着一个你
流过的泪滴 全都因为你
原来迟迟都 不曾放下你
或许我们就不该 有段因果
或许我不该 一味求施舍
如果有天 我离开了你的生活
如果有天 你还爱着我
姑娘为何你要放声哭泣
我在路那旁 小河等你
你心里到底藏了什么秘密
我想紧紧的抱住你
你说遇到的人全都像你
找不到失去你的意义
你说你克制着 不再想起
可是我就在你心里
秒针的声音 嘀嗒转不停
我的心里 住着一个你
流过的泪滴 全都因为你
原来迟迟都 不曾放下你
或许我们就不该 有段因果
或许我不该 一味求施舍
如果有天 我离开了你的生活
如果有天 你还爱着我
姑娘为何你要放声哭泣
我在路那旁小河等你
你心里到底藏了什么秘密
我想紧紧的抱住你
你说遇到的人全都像你
找不到失去你的意义
你说你克制着不再想起
可是我就在你心里`,
},
{
deptName: "寂寞沙洲冷",
deptValue: `自你走后心憔悴
白色油桐风中纷飞
落花似人有情这个季节
河畔的风放肆拼命的吹
无端拨弄离人的眼泪
那样浓烈的爱再也无法给
伤感一夜一夜
当记忆的线缠绕过往支离破碎
是慌乱占据了心扉
有花儿伴着蝴蝶孤雁可以双飞
夜深人静独徘徊
当幸福恋人寄来红色分享喜悦
闭上双眼难过头也不敢回
仍然拣尽寒枝不肯安歇
微带着后悔
寂寞沙洲我该思念谁
自你走后心憔悴
白色油桐风中纷飞
落花似人有情这个季节
河畔的风放肆拼命的吹
无端拨弄离人的眼泪
那样浓烈的爱再也无法给
伤感一夜一夜
当记忆的线缠绕过往支离破碎
是慌乱占据了心扉
有花儿伴着蝴蝶孤雁可以双飞
夜深人静独徘徊
当幸福恋人寄来红色分享喜悦
闭上双眼难过头也不敢回
仍然拣尽寒枝不肯安歇
微带着后悔
寂寞沙洲我该思念谁
当记忆的线缠绕过往支离破碎
是慌乱占据了心扉
有花儿伴着蝴蝶孤雁可以双飞
夜深人静独徘徊
当幸福恋人寄来红色分享喜悦
闭上双眼难过头也不敢回
仍然拣尽寒枝不肯安歇
微带着后悔
寂寞沙洲我该思念谁
仍然拣尽寒枝不肯安歇
微带着后悔
寂寞沙洲我该思念谁`,
},
{
deptName: "下一个天亮",
deptValue: `用起伏的背影挡住哭泣的
有些故事不必说给每个人
许多眼睛看的太浅太
错过我没被看见那个自
用简单的言语解开超载的
有些情绪是该说给懂的人
你的热泪比我激动怜
我发誓要更努力更有勇
等下一个天
去上次牵手赏花那里散步好
有些积雪会自己融
你的肩膀是我豁达的天
等下一个天
把偷拍我看海的照片送我好
我喜欢我飞舞的头
和飘着雨还是眺望的眼
用简单的言语解开超载的
有些情绪是该说给懂的人
你的热泪比我激动怜
我发誓要更努力更有勇
等下一个天
去上次牵手赏花那里散步好
有些积雪会自己融
你的肩膀是我豁达的天
等下一个天
把偷拍我看海的照片送我好
我喜欢我飞舞的头
和飘着雨还是眺望的眼
时间可以磨去我的棱
有些坚持却永远磨不
请容许我小小的骄
因为有你这样的依
等下一个天
去上次牵手赏花那里散步好
有些积雪会自己融
你的肩膀是我豁达的天
等下一个天
把偷拍我看海的照片送我好
我喜欢我飞舞的头
和飘着雨还是眺望的眼光`,
},
{
deptName: "离别开出花",
deptValue: `坐上那朵离家的云霞
飘去无人知晓的天涯
背着妈妈说的那句话
孩子人生其实不复杂
喔~眼泪轻轻地擦
别管那多嘴乌鸦
咽下那些风沙
你才能慢慢长大
要错过几个她
用你最好的年华
这是青春的代价
当离别开出花
伸出新长的枝桠
像冬去春又来
等待心雪融化
你每次离开家
带着远方的牵挂
那城市的繁华
盖住了月牙
当离别开出花
它生长在悬崖
在最高的山顶
才听得见回答
没什么好害怕
孩子放心去飞吧
在你的身后
有个等你的家
坐上那朵离家的云霞
飘去无人知晓的天涯
背着妈妈说的那句话
孩子人生其实不复杂
喔~眼泪轻轻地擦
别忘那童年梦话
散在远方的花
也随风慢慢长大
要错过几个她
用你最真的年华
这是青春的回答
当离别开出花
伸出新长的枝桠
像冬去春又来
等待心雪融化
你每次离开家
带着远方的牵挂
那城市的繁华
盖住了月牙
当离别开出花
它生长在悬崖
在最高的山顶
才听得见回答
没什么好害怕
孩子放心去飞吧
在你的身后
有个等你的家
当离别开出花
伸出新长的枝桠
像冬去春又来
等待心雪融化
你每次离开家
带着远方的牵挂
那城市的繁华
盖住了月牙
当离别开出花
它生长在悬崖
在最高的山顶
才听得见回答
没什么好害怕
孩子放心去飞吧
在你的身后
有个等你的家`,
},
{
deptName: "我想离开浪浪山",
deptValue: `我想离开浪浪山
是不是该出去闯闯
哎呀 别瞎想
能有的干就不错了
你跟着大王好好干
争取早日修炼成精
这才是正事
天上的星星在闪烁
有没有一颗属于我
它时常提醒着我 别犯错
回家的路多少曲折
泪眼婆娑月影斑驳
故乡的烛火 在梦里闪烁
这个世界好像每天都在重播
也许离开浪浪山一个人生活
还是就这样继续得过且过
怎么好像从来没有人在意过
现在的我到底快不快乐
就好像离岸的船 无处可停泊
可我有时真的有点不知所措
迎合太多反而显得笨拙
到底那是怎样的我
一年都没回来
是不是太忙了
对对对
现在大王给我派了很多事情
每天做都做不完
哎呀 大王重视你就好
这个世界好像每天都在重播
也许离开浪浪山一个人生活
还是就这样继续得过且过
怎么好像从来没有人在意过
现在的我到底快不快乐
就好像离岸的船 无处可停泊
可我有时真的有点不知所措
迎合太多反而显得笨拙
到底那是怎样的我
天上的星星在闪烁
有没有一颗属于我
它时常提醒着我 别犯错
回家的路多少曲折
泪眼婆娑月影斑驳
故乡的烛火 在梦里闪烁
你也不要太拼了
你这一个人在外面
也没人照顾
我想离开浪浪山`,
},
],
};
},
methods: {
// 防抖
debounce(func, wait, immediate) {
var timeout, args, context, timestamp, result;
var later = function () {
// 据上一次触发时间间隔
var last = new Date() - timestamp;
// 上次被包装函数被调用时间间隔last小于设定时间间隔wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args);
if (!timeout) context = args = null;
}
}
};
return function () {
context = this;
args = arguments;
timestamp = new Date();
var callNow = immediate && !timeout;
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
}
return result;
};
},
navClick(index) {
var scrollBox1 = document.querySelector(".container");
scrollBox1.scrollTo(0, document.getElementById(`div${index}`).offsetTop);
this.selectedItem = index;
},
},
mounted() {
var self = this;
var doc = document;
var $scrollBox = doc.querySelector(".container");
var scrollCallback = self.debounce(function () {
var top = $scrollBox.scrollTop; //设置变量top,表示当前滚动条到顶部的值
for (var n = 0; n < self.domainLineList.length; n++) {
//在此处通过判断滚动条到顶部的值和当前窗口高度的关系来取得和导航索引值的对应关系
if (top >= doc.getElementById(`div${n}`).offsetTop) {
if (doc.getElementById(`div${n + 1}`)) {
if (top <= doc.getElementById(`div${n + 1}`).offsetTop) {
self.selectedItem = n;
}
} else {
self.selectedItem = self.domainLineList.length - 1;
}
}
}
}, 500);
$scrollBox.addEventListener("scroll", scrollCallback);
},
};
</script>
css 部分
<style lang="scss" scoped>
body,
html {
height: 100%;
}
#app,
* {
margin: 0;
padding: 0;
}
.nav li a:hover {
border-bottom: 2px solid #0052e4;
}
.bbactive {
border-bottom: 2px solid #0052e4;
}
li {
list-style-type: none;
}
a {
text-decoration: none;
outline: 0;
}
.container {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
overflow: auto;
width: 800px;
height: 500px;
margin: auto;
}
.nav {
position: fixed;
z-index: 5;
display: inline-flex;
flex-wrap: wrap;
width: 150px;
height: inherit;
background: #fff;
}
.nav li {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
.nav li a {
font-size: 18px;
display: block;
padding: 10px 5px;
cursor: pointer;
color: #3c3c3c;
}
article {
display: inline-block;
width: 80%;
margin-left: 150px;
}
article > h1 {
width: 100%;
padding: 10px;
border-bottom: 1px solid #000;
}
</style>