這個目錄索引應該包含如下功能: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