為博客園開發了一套腳手架及模板——實時預覽頁面定製效果

来源:https://www.cnblogs.com/immx/archive/2022/04/06/cnblogx.html
-Advertisement-
Play Games

有時大家可能會想為自己的博客增添一些色彩,但這種熱情卻常常因繁雜的配置步驟飽受消磨。CNBlogX是一套項目模板及腳手架的合集,用於快速搭建博客園的頁面定製腳本開發環境。使用方式也非常簡單,專註於自己的代碼即可。讓我們開始吧! ...


banner


有時大家可能會想為自己的博客增添一些色彩,但這種熱情卻常常因繁雜的配置步驟飽受消磨。CNBlogX是一套項目模板及腳手架的合集,用於快速搭建博客園的頁面定製腳本開發環境。使用方式也非常簡單,專註於自己的代碼即可。讓我們開始吧!

起步

  • 請確保全裝了Node.js,需要14.0或更新的版本。

通過以下命令基於CNBlogX模板創建一個叫做mytheme的項目:

npm init cnblogx mytheme

這樣項目就建立完成了,讓我們看看src/下的代碼:

image

非常簡潔,不必關心CNBlogX在背後做了什麼,我們只要在這三個文件中添加代碼即可。如果有定製化的需要,可以查看README.md中的可配置項,接下來讓我們把代碼部署到博客園。

首次部署

首先給我們的項目安裝依賴:

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 © 你的名字,可退出開發者模式。

實踐:編寫常用組件

讓我們寫幾個常用的博客組件,體驗一下熱模塊替換帶來的效率提升吧!後文中出現的組件可以在這個項目中找到。

評論區頭像

第一版:低解析度頭像

博客園預設不顯示評論區用戶的頭像,但在評論區中提供了每位用戶的頭像鏈接,我們可以通過瀏覽器的開發者工具看到:

image

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

image

嗯... 好像有一點糊,這個頭像解析度太低了。

第二版:回退式高清頭像

經過觀察,我們發現個人主頁的頭像鏈接和評論區的頭像鏈接只存在一個目錄的差異:

image

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

image

第三版:二級回退式頭像

有時會發現,個別用戶根本沒有頭像,我們可以為他們添加一個預設頭像。那麼我們的代碼至多可能有兩次回退,高清頭像->普通頭像->預設頭像,像這樣:

avatar = document.createElement('img');
avatar.src = get_hi_definition_avatar_src(addr); // 設置為高清頭像。
avatar.addEventListener('error', () => {
    if (avatar.src != addr) {
        avatar.src = addr; // 回退到低解析度頭像。
    } else {
        avatar.replaceWith(new_default_avatar(nick)); // 回退到預設頭像。
    }
});

接下來讓我們給用戶畫一個預設頭像吧!

image

我們把衣服的位置鏤空,再給頭像元素設置不同的背景色,就可以為不同的用戶顯示不同顏色的頭像了!完整代碼可以看這裡

隨筆目錄

雖然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就更歡迎了。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • OpenHarmony 開源開發者成長計劃第二期知識賦能直播課程以入門為主,共設置 8 節課,覆蓋了應用開發、設備開發、內核驅動等多個技術領域。 ...
  • 前言 ​ 我們主要介紹如何實現控制項點擊事件($AppClick)的全埋點。在介紹如何實現之前,我們需要先瞭解一下,在 UIKit 框架下,處理點擊或拖動事件的 Target-Action 設計模式。 一、 Target-Action ​ Target-Action,也叫目標-動作模式,即當某個事件發 ...
  • 日益多元化的廣告形式以及投放成本的不斷攀升,讓廣告主們更加關註每一次廣告投放帶來的實際價值。 然而,廣告主一般僅能從平臺獲得展示、點擊、下載等前端效果欄位,實際的用戶註冊、激活等後端深度轉化指標並無法獲取。 如何科學衡量廣告投放效果? 新增用戶到底來源於自然增量還是推廣買量?這些,您通過HMS Co ...
  • 關於ANSI Color的一些鮮為人知的秘密 揭秘如何在終端中顯示五彩斑斕的字元 ...
  • 利用JavaScript函數做一個簡單的倒計時 <script> // 代碼如下: function countDown(time) { var nowTime = +new Date(); // 返回的是當前時間總的毫秒數 var inputTime = +new Date(time); // 返 ...
  • 前言 截止到四月,我在目前這家公司工作已是整整一年時間。多次想寫篇文章做做總結,記錄一下這一年的成長。 工作 必要的技術廣度 足夠寬泛的知識面能夠幫助企業做出提效降本的正確決策。為此我還做過一篇記錄。鏈接:https://www.cnblogs.com/WeiFE/p/15510423.html 技 ...
  • 1、介面 1.對象中使用中括弧是設置key的類型是字元串,冒號後面就是鍵值對的值; 2.介面只是用來形容給進來的數據必須符合介面類型內容,所以不能賦值; export default interface IBox{ a:number; b:string; [key:string]:number |s ...
  • 指數運算符 ** console.log(2 ** 2 ) //4 console.log(2 ** 3 ) //8 console.log(2 ** 4) //16 鏈判斷運算符的誕生(?.) 在實際編程中, 如果讀取對象內部的某個屬性,往往需要判斷一下。 屬性的上層對象是否存在。比如,讀取 me ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...