一、成果概述
基于博客(三),由于长博客看起来比较乱,所以加上了导航功能,导航栏可以帮助作者理清文章顺序,同时也能帮读者快速定位关键词。
二、实现思路
发布文章:
配置 toc 生成导航时包含的标题,标题范围是h1-h6:
VMdEditor.use(githubTheme, {
config: {
toc: {
includeLevel: [1,2,3,4,5,6],
},
},
});
配置生成目录导航时包含的标题:
<v-md-editor :include-level="[1,2,3,4,5,6]"></v-md-editor>
效果展示:
阅读文章:
<el-card>
<h1>·目录导航</h1><br>
<!-- 自定义锚点:目录导航 -->
<div
:key="anchor"
v-for="anchor in titles"
:style="{ padding: `10px 0 10px ${anchor.indent * 20}px`}"
@click="handleAnchorClick(anchor)">
<a style="cursor: pointer; color: #3faadb">{{ anchor.title }}</a>
</div>
</el-card>
其中titles[]存的是文章内容content筛选后的标题(h1~h6),利用querySelectorAll获取所有dom,详细代码:
getCatalog(){
const anchors = this.$refs.preview.$el.querySelectorAll('h1,h2,h3,h4,h5,h6');
const titles = Array.from(anchors).filter((title) => !!title.innerText.trim()); //过滤文本内容不为空的要素
console.log(titles)
if (!titles.length) {
this.titles = [];
return;
}
const hTags = Array.from(new Set(titles.map((title) => title.tagName))).sort();
this.titles = titles.map((el) => ({
title: el.innerText,
lineIndex: el.getAttribute('data-v-md-line'),
indent: hTags.indexOf(el.tagName),
}));
},
点击当行,定位到相应区域:
//标题导航点击
handleAnchorClick(anchor) {
const { preview } = this.$refs;
const { lineIndex } = anchor;
const heading = preview.$el.querySelector(`[data-v-md-line="${lineIndex}"]`);
if (heading) {
// 注意:如果你使用的是编辑组件的预览模式,则这里的方法名改为 previewScrollToTarget
preview.scrollToTarget({
target: heading,
scrollContainer: window,
top: 60,
});
}
},
前端效果:
发现在滑动文章后,导航也跟着消失,这样的设计非常不友好,于是加上了导航吸顶的效果。
导航吸顶:
<div style="width: 30%;" :class="navBarFixed === true ? 'navBarWrap' :''">
监听页面滚动:
一旦navBarFixed为true,便把:class与navBarWrap相关联;
mounted() {
window.addEventListener("scroll", this.watchScroll); //监听滚动
},
methods: {
//滚动
watchScroll() {
var scrollTop =
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop;
console.log(scrollTop)
// 当滚动超过 90 时,实现吸顶效果
if (scrollTop > 90) {
this.navBarFixed = true;
} else {
this.navBarFixed = false;
}
},
}
<style scoped>
.navBarWrap {
position:fixed; //固定组件
right: 0;
top: 0;
z-index:999;
}
</style>
效果展示: