
有時大家可能會想為自己的博客增添一些色彩,但這種熱情卻常常因繁雜的配置步驟飽受消磨,CNBlogX是一套專案模板及腳手架的合集,用于快速搭建博客園的頁面定制腳本開發環境,使用方式也非常簡單,專注于自己的代碼即可,讓我們開始吧!
起步
- 請確保安裝了Node.js,需要14.0或更新的版本,
通過以下命令基于CNBlogX模板創建一個叫做mytheme的專案:
npm init cnblogx mytheme
這樣專案就建立完成了,讓我們看看src/下的代碼:

非常簡潔,不必關心CNBlogX在背后做了什么,我們只要在這三個檔案中添加代碼即可,如果有定制化的需要,可以查看README.md中的可配置項,接下來讓我們把代碼部署到博客園,
首次部署
- 若依賴安裝很慢,可以考慮先配置npm淘寶鏡像源,
首先給我們的專案安裝依賴:
npm install
再編譯我們的專案:
npm run build
然后將dist/下的生成物復制到博客園-管理-設定的對應選項中:
- 將
custom.css的內容復制到頁面定制CSS代碼中, - 將
custom.html的內容復制到頁腳HTML代碼中,
最后保存博客后臺設定即可,
首次部署是必要的步驟,CNBlogX在構建時插入了開發者模式相關代碼,接下來讓我們體驗一下,
開發者模式
- 請確保已經完成首次部署,
首先執行以下命令啟動除錯服務器,它將監視代碼變化并將其應用到博客頁面中:
npm run dev
然后瀏覽器中打開自己的博客,雙擊頁腳的Copyright ? 你的名字,進入開發者模式,
此后,若src/下對應的檔案發生了變化,這些變化將立即被應用到博客頁面中:
main.ejs:支持HTML/EJS(兼容,后綴不可更改),main.js:支持Javascript/Typescript(更改后綴為.ts即可支持Typescript),main.scss:支持CSS/SCSS(兼容,后綴不可更改),
- 再次雙擊頁腳的Copyright ? 你的名字,可退出開發者模式,
實踐:撰寫常用組件
讓我們寫幾個常用的博客組件,體驗一下熱模塊替換帶來的效率提升吧!后文中出現的組件可以在這個專案中找到,
評論區頭像
第一版:低解析度頭像
博客園默認不顯示評論區用戶的頭像,但在評論區中提供了每位用戶的頭像鏈接,我們可以通過瀏覽器的開發者工具看到:

所以我們只要通過Javascript新建一個img標簽,顯示對應鏈接的頭像即可:

嗯... 好像有一點糊,這個頭像解析度太低了,
第二版:回退式高清頭像
經過觀察,我們發現個人主頁的頭像鏈接和評論區的頭像鏈接只存在一個目錄的差異:

那我們可以先顯示這個清晰的頭像,如果獲取失敗了,再回退到低解析度的頭像,效果非常不錯:

第三版:二級回退式頭像
有時會發現,個別用戶根本沒有頭像,我們可以為他們添加一個默認頭像,那么我們的代碼至多可能有兩次回退,高清頭像->普通頭像->默認頭像,像這樣:
avatar = document.createElement('img');
avatar.src = https://www.cnblogs.com/immx/archive/2022/04/06/get_hi_definition_avatar_src(addr); // 設定為高清頭像,
avatar.addEventListener('error', () => {
if (avatar.src != addr) {
avatar.src = https://www.cnblogs.com/immx/archive/2022/04/06/addr; // 回退到低解析度頭像,
} else {
avatar.replaceWith(new_default_avatar(nick)); // 回退到默認頭像,
}
});
接下來讓我們給用戶畫一個默認頭像吧!

我們把衣服的位置鏤空,再給頭像元素設定不同的背景色,就可以為不同的用戶顯示不同顏色的頭像了!完整代碼可以看這里,
隨筆目錄
雖然Markdown允許通過[toc]創建一個目錄,但每次都要回到頂部查看目錄并不方便,讓我們也寫一個目錄吧,
堆疊:將陣列轉換為一棵樹
目錄通常是多級的,大標題包含小標題,我們可以用.querySelectorAll()將文章中所有的標題收集到一個陣列中,然后通過一個堆疊將線性的陣列轉化為一棵樹,像這樣:
article.querySelectorAll('h1,h2,h3,h4,h5,h6').forEach(function (header) {
const node = CreateTocNode(header);
for (; ;) {
if (node_stack.top().level < node.level) {
node_stack.top().add_toc_child(node);
node_stack.push(node);
break;
} else {
node_stack.pop();
}
}
});
下一個功能是讓目錄高亮當前小節的標題,
不妨將「當前小節的標題」定義為「離螢屏頂端最近的一個標題」,那么思路就清晰起來了:注冊一個滾動事件,于事件發生時遍歷所有的標題,找到getBoundingClientRect().top的絕對值最小的一個,賦予其一個表示高亮的類名即可,
不過,這樸素的思路存在著一定的效率問題,下面我們將對它做出一些優化,
節流:防止滾動事件頻繁觸發
頁面滾動時,滾動事件連續觸發的頻率非常高,可以用一個節流函式降低更新高亮目錄的頻率,同時為了避免節流函式導致丟失滾動快結束時的滾動事件,添加一個會被不斷重置的setTimeout即可,代碼是這樣的:
let timeout = null;
regi_scroll(throttle(() => {
update_current_node();
if (!timeout) {
timeout = setTimeout(() => {
update_current_node();
timeout = null;
}, 400);
}
}, 200));
二分搜索:獲取當前小節的標題
標題們的getBoundingClientRect().top雖然有正有負,但只要是遞增的,就可以應用二分搜索,通過二分搜索找到top值在零附近的至多兩個標題,再從中取top的絕對值最小的一個即可,代碼是這樣的:
let left = 0;
let right = node_list.length - 1;
while (left + 1 < right) {
const mid = Math.floor((left + right) / 2);
if (node_list[mid].top <= 0) {
left = mid;
} else {
right = mid;
}
}
實作目錄大概用了一百行左右的代碼,可以在這里查看,
常見問題
我的專案能夠與其它代碼共存嗎?
CNBlogX默認會在進入開發者模式時清除用戶的頁面定制CSS代碼,以免用戶混淆部署版本與開發版本的樣式,可以通過PRESERVE_CSS編譯選項阻止這個默認行為,
- 推薦將代碼遷移到你的CNBlogX專案中,若希望在除錯時開啟
PRESERVE_CSS編譯選項,推薦先部署packed編譯模式生成的代碼,
有離線的檔案嗎?
有的,看專案根目錄下的README.md,通過腳手架建立的新專案與Github上的模板只有包名不同,
開發者模式會影響他人閱讀嗎?
不會,開發者模式僅對啟用它的單個瀏覽器有效,
- 要令博客定制代碼對所有讀者生效,需要一次新的部署,
為什么有時js的更改在重繪后才生效?
因為相關的模塊存在未消除的副作用,參考熱模塊替換的檔案,
可以單獨生成.js檔案嗎?
可以,通過STANDALONE_JS編譯選項生成單獨的.js檔案,通過PUBLIC_PATH編譯選項可令.html檔案從指定的路徑加載.js檔案,
可以自定義埠嗎?
可以,通過PORT編譯選項配置埠,博客園中的代碼與本地測驗服務器的代碼配置的埠應當相同,
沒有頁腳的博客如何進入開發者模式?
打開瀏覽器的控制臺,執行以下代碼即可:
cnblogx_development(true);
結語
希望大家喜歡,意見或建議也是很歡迎的,Issue或Pull Request就更歡迎了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/457058.html
標籤:其他
上一篇:如何在控制臺列印彩色文字-你不知道的ANSI Color
下一篇:有關TypeScript感觸集錦
