这个目录索引应该包含如下功能:javascript
话很少说,开始干!css
说到文章的目录索引,首先想到的就是锚点了。然而在hash
模式的路由下,若是使用原始的锚点方案会形成下面这样的问题。vue
// 文章url连接,hash模式下 www.rychou.xyz/#/article/70 // 若是采用传统的锚点方式,好比有个锚点:anchor-1,点击以后,url会变成 www.rychou.xyz/#anchor-1
很明显,在hash
模式下,就不能采用这种方式锚点了。我采用了自定义锚点的方式。java
参考: vue2.0中怎么作锚点定位
方法有了,而后就是怎么给文章加添加锚点了。web
我采用了遍历dom树,而后找到文章的h1
标签(暂时只对h1
标签创建索引),为其添加id
的方式创建索引。segmentfault
// 初始化文章锚点和目录数据结构 getDirectories() { let directories = document.querySelectorAll(".article-content h1"); //找到属于文章内容的h1标签 directories.forEach((element, index) => { element.id = "anchor-" + index;//添加id this.directories.push({ title: element.innerText, //h1标签文本内容 offsetTop: element.offsetTop, //记录当前h1标签的偏移量,方便后面计算滚动距离。 isActive: false //是否被选中 }); });
<div v-for="(item,index) in directories" :key="index"> <a href="javascript:void(0)" @click="goAnchor(index)" > {{item.title}} </a> </div> methods:{ goAnchor(index) { document.documentElement.scrollTop = this.directories[index].offsetTop; }, }
注意咱们前面初始化目录数据结构中,包含了一个叫isActive
的状态位,就是根据这个状态位来进行相应的渲染数据结构
class
<div class="directories-container"> <div class="directories-list"> <h2>目录</h2> <div :class="{'highlight-title':item.isActive}" v-for="(item,index) in directories" :key="index" style="padding: 5px 12px;"> <a href="javascript:void(0)" @click="goAnchor(index)" > {{item.title}} </a> </div> </div> </div>
// 挂载页面时,添加滚动监听 mounted() { window.addEventListener("scroll", this.handleScroll); }, // 退出页面时,应该取消监听 destroyed() { window.removeEventListener("scroll", this.handleScroll); },
isActive
handleScroll(e) { let scrollTop = document.documentElement.scrollTop //当前滚动距离 this.directories.forEach((element,index)=>{ if((scrollTop)>=element.offsetTop){//当前滚动距离大于某一目录项时。 for(let i=0;i<index;i++){ this.directories[i].isActive = false //同一时刻,只能有一个目录项的状态位为Active,即此时其余目录项的isActive = false } element.isActive = true; //将对应的目录项状态位置为true }else{ element.isActive = false; } }) }
// scss .directories-container { width: 15vw; transition: all 0.5s; margin-left: 10px; .highlight-title { border-left: 3px solid rgb(15, 105, 223); background-color: rgb(243, 243, 243); z-index: -1; a{ color: rgb(15, 105, 223) } } .directories-list { position: -webkit-sticky; position: sticky; top: 0; word-wrap: break-word; background-color: #fff; border-left: 1px solid rgb(236, 236, 236); z-index: 999; a { &:hover { text-decoration: underline; } } } }
原文连接: 为你的博客添加目录索引
欢迎关注公众号:开源学院dom