爲你的博客添加目錄索引

1、前言

演示圖例

GIF.gif

需求

這個目錄索引應該包含如下功能:javascript

  • 點擊目錄項跳轉到對應錨點
  • 屏幕滾動時,對應目錄項樣式變化

話很少說,開始幹!css

2、點擊目錄項跳轉到對應錨點

hash模式的路由下的錨點

說到文章的目錄索引,首先想到的就是錨點了。然而在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;
    },
}

3、屏幕滾動時,對應目錄項樣式變化

注意咱們前面初始化目錄數據結構中,包含了一個叫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;
        }
      })
}

css樣式

// 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

相關文章
相關標籤/搜索