Hexo Basic

Hexo TocHelper 錯誤及其修正

問題

Hexo的TocHelper生成的目錄,其中的連結無法導向文章的標題,是出了什麼問題?

首先我們去看那個元素,發現這個a缺少了href。

1
<a class="toc-link"><span class="toc-text">Using Firebase via CDN</span></a>

解決

首先,我們搜尋toc這個關鍵字,在node_modules\hexo\lib\plugins\helper\toc.js找到function tocHelper ,就是我們要修正的目標。

可以看到,a.toc-link的href若無,則會生成沒有href的a

1
2
3
4
5
if (href) {
result += `<a class="${className}-link" href="${href}">`;
} else {
result += `<a class="${className}-link">`;
}

從這裡可以知道,href是由id作成的,而id是來自於el,el則是data的item

1
2
3
4
5
6
for (let i = 0, len = data.length; i < len; i++) {
const el = data[i];
const { level, id, text } = el;
const href = id ? `#${encodeURL(id)}` : null;
//...
}

我們試著把data Print出來,注意,不是在瀏覽器,而是在你的node terminal。

1
2
3
4
5
6
7
console.log(data)
for (let i = 0, len = data.length; i < len; i++) {
const el = data[i];
const { level, id, text } = el;
const href = id ? `#${encodeURL(id)}` : null;
//...
}

在for之前的data是長這樣的,可以發現,id是 "",也就是空白字串,而text則是我們可以拿來用的東西

1
2
3
4
5
6
7
8
9
10
[
{ text: '使用Firebase', id: '', level: 1 },
{ text: '前言', id: '', level: 1 },
{ text: '安裝', id: '', level: 1 },
{ text: 'Using Firebase via CDN', id: '', level: 2 },
{ text: 'Using Firebase via NPM', id: '', level: 2 },
{ text: '實作', id: '', level: 1 },
{ text: '在Angular使用Firebase', id: '', level: 2 },
{ text: '自訂FirebaseAuth介面', id: '', level: 2 }
]

在hexo html的id生成時,若遇到空格,會自動加上-,然後變成小寫。例如 'Using Firebase via CDN' 這個文字要轉成id,會變成 using-firebase-via-cdn,我們就依照這個原則去寫一個方程式將text轉成可用的id。

在下方,我寫了一個 encodedText function去修正text,生出來的id就是符合上述規範,要把它改成href的話,只要在前面加上 # 即可。

1
2
3
4
5
6
7
8
9
10
11
12
for (let i = 0, len = data.length; i < len; i++) {
let encodedText = function(txt){
let new_txt = String(txt).toLowerCase().replace(/ /g, "-");
console.log(new_txt)
return new_txt;
}
const el = data[i];
const { level, id, text } = el;
// const href = id ? `#${encodeURL(id)}` : null;
const href = text ? `#${encodedText(text)}` : null;
//...
}

以下是成功修正後的a

1
<a class="toc-link" href="#using-firebase-via-cdn"><span class="toc-text">Using Firebase via CDN</span></a>

問題解決。

閱讀全文