原文地址傳送門:為jekyll博客添加目錄與scrollspy效果?
隨著網(wǎng)上利用Jekyll+Github Pages搭建個人靜態(tài)博客的帖子越來越多,按照教程自己動手搭一個基于Github賬戶的博客已完全成為一個五分鐘速成課程的內(nèi)容了。網(wǎng)上也隨處可見優(yōu)美的博客主題,且能完全即插即用。但對于一些想要更深入定制化的博主,本文主要集合自己折騰的經(jīng)驗介紹下如何給Jekyll博客添加目錄(即Table of Content)以及定制化目錄顯示的ScrollSpy效果。
如下圖所示,生成ScrollSpy效果的目錄結(jié)構(gòu)主要有三個部分。
1 目錄生成插件選擇
Jekyll官網(wǎng)上的plugins目錄下便列出了很多有用的插件,其中關(guān)于目錄生成的jekyll-toc-generator便是官方推薦的。但對于在Github上建站的同學應(yīng)該知道,Github禁止了很多plugins的自動build,盡管也正在增加一些插件白名單,但貌似這個插件是不能通過源碼提交給Github pages自動build的。因此對于不想通過設(shè)定.nojekyll 本地build,然后push整個靜態(tài)代碼到Github上的同學,可能一些純javascript的插件便是首選。
1-a 純JS版本
本文所用的便是純javascript版的toc插件jekyll-table-of-contents. 其README也很詳細,照著一步步配即可。
* 在待添加插件的模板中首先加入jquery.js的依賴,然后是把該toc.js放在其后。
在需要顯示目錄結(jié)構(gòu)的地方加上如下div。
把toc.js調(diào)用函數(shù)放在最后(如之前)即可。
$(document).ready(function(){$('#toc').toc();});
2 Markdown實現(xiàn)版本
Toc插件生成目錄的原理便是借助markdown為每個header生成一個唯一的id,然后Toc便會尋找這樣的header id逐一的構(gòu)造相應(yīng)的錨鏈接,并顯示即可。
常見的Markdown實現(xiàn)如rdiscount,kramdown,redcarpet。不同的版本,需要在_config.yml文件中進行相應(yīng)的配置。如對于rdiscount,配置如下:
markdown: rdiscount
rdiscount:
? ? ? ? ? extensions:
? ? ? ? ? ? ? ? ?- generate_toc
值得說明的是,我發(fā)現(xiàn)rdiscount對每個header會生成相同的id,便導致了Toc插件生成的所有目錄都被定向到同一個錨鏈接。在網(wǎng)上收了下有一些issues談到這方面的問題,如:
1.https://github.com/jekyll/jekyll/issues/110
2.https://github.com/jekyll/jekyll/issues/471
3.https://github.com/ghiculescu/jekyll-table-of-contents/issues/16
所以如果有同學遇到類似的情況,可以用其他的markdown版本,如redcarpet.
對于redcarpet,配置如下:
markdown: redcarpet
redcarpet:
? ? ? ?extensions: [with_toc_data]
用redcarpet時同樣值得注意的是,對于使用串來做摘要分割符的會發(fā)現(xiàn)redcarpet并不能根據(jù)其來準確的截取相應(yīng)的摘要串。原因便是redcarpet會對一些字符如<,>進行轉(zhuǎn)義,變成相應(yīng)的<,>。
2-a 錨鏈接縮進問題
當你為網(wǎng)頁設(shè)置了一個固定位置的導航欄(具有確定的高度),然后你為其他頁面內(nèi)容生成了錨鏈接(如本文提到的目錄結(jié)構(gòu))。當你點擊錨鏈接時,頁面會跳轉(zhuǎn)到相應(yīng)的錨鏈接位置,且該錨鏈接的起始點會縮進到最上方,而部分被導航欄遮住。如下表左表所示:
點擊:http://foo.com/#bar
錯誤 (but the common behavior):? ? ? ? 正確:
+---------------------------------+? ? ? +---------------------------------+
? ? | BAR///////////////////// header | ? ? ? ? ? ? ?| //////////////////////// header |
+---------------------------------+? ? ? +---------------------------------+
| Here is the rest of the Text? ? | ? ? ? ? ? ? ? ? ? ? ? ?| BAR? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| ...? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| ...? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Here is the rest of the Text? ? |
| ...? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ...? ? ? ? ? ? ? ? ? ? ? ? ? ? |
+---------------------------------+? ? ? +---------------------------------+
而你希望的行為則是如右表所示的。對此,可以在toc腳本生成header時為其添加一個div的class,
然后在css中設(shè)置起式樣為:
/* 具體padding高度可以根據(jù)你導航欄的高度來設(shè)定 */.anchor{padding-top:50px;}
3 為目錄顯示添加scrollspy效果
scrollspy效果即導航欄或目錄會隨著頁面的滑動位置自動顯示當前所在的段落所屬的導航條目。其主要是基于著名的bootstrap來實現(xiàn)的。W3Cschool上有一個設(shè)置scrollSpy的簡單教程。但其主要是針對手動設(shè)置header id的情況。針對通過toc.js自動生成header id的配置如下:
添加bootstrap式樣頭和腳本
在你想要操作的頁面范圍內(nèi)(通常是)內(nèi)設(shè)置滾動事件的響應(yīng)目標(可以是id或是class,此處我們用toc表示目錄),如下:
設(shè)置你的toc div:
/* 你的scrollSpy目錄結(jié)構(gòu)將要顯示在這里 */
在你的toc.js腳本中添加bootstrap中的`nav nav-pills nav-stacked`類:
/* 把 html = settings.title + " <" + settings.listType + ">" 變成如下 */html=settings.title+" <"+settings.listType+" class = 'nav nav-pills nav-stacked'>";
So long, and Thanks for all the fish.
參考
[2].positionfixed-page-header-and-anchors.
[3].W3cScholl.