文件 1.11.6

渲染與同步

本頁說明 MDViewer 何時重新渲染、渲染時做了哪些事,以及與編輯器的捲動同步如何運作。

觸發時機

來源 條件
編輯器 keyup autosave 為真,且按鍵不是方向鍵、Shift、Control、Alt、CapsLock、Escape、F1~F12、Meta
編輯器格式化方法(bold()、heading() 等) autosave 為真
undo()、redo() autosave 為真
clear()、openfile() 讀取完成 一律觸發
save() autosave 為假時觸發(Cmd/Ctrl+S 或工具列「儲存並預覽」)
直接呼叫 viewer.init(text) 一律觸發

autosave: false 時,輸入不會即時反映到預覽,只有 save() 才會更新。

渲染步驟

viewer.init(txt) 的流程:

  1. 設 data-saved="1",清除上一個計時器
  2. 等待 sync.delay 毫秒(預設 300;傳 0 會因 falsy 回到 300)
  3. 決定內容:txt → 綁定編輯器的文字 → emptyContent,取第一個非空值
  4. 呼叫 transToHTML()(擴充模式,帶 hashtag 設定)
  5. 以 replaceChildren() 整段替換預覽器內容
  6. 為每個程式碼區塊的複製按鈕綁定 navigator.clipboard.writeText();成功時加 success class 1 秒,失敗加 error class
  7. 每 50 ms 檢查 code-prettify 的全域 PR 是否載入;載入後還原捲動位置、執行 PR.prettyPrint(),再對整份文件的 .mermaid 元素執行 mermaid.run()

連續輸入時計時器會被重設,只有停止輸入超過 sync.delay 才會真正渲染(debounce)。

讀取編輯器文字

預覽器不透過事件拿資料,而是在渲染時讀取編輯器容器中每個 <div> 列的 innerText:空白列變成單一 \n,不換行空白換成一般空白,最後整體 trim()。

捲動同步

sync.scroll 為真時,綁定編輯器的當下會設定編輯器的 onwheel:每次滾輪事件把 deltaY 加到預覽器的 scrollTop。

限制 說明
只同步滾輪 拖曳捲軸、觸控滑動、鍵盤捲動不會同步
單向 只有編輯器帶動預覽器
依增量 不是比例對應,兩邊內容高度差異大時位置會漂移
覆寫 onwheel 會取代編輯器容器上既有的 onwheel handler

儲存狀態旗標

編輯器與預覽器容器的 data-saved 屬性反映內容是否已同步:輸入後設為 0(unsave()),渲染開始時設為 1。NanoMD.css 依此屬性顯示狀態,也可用於自訂「未儲存」提示。

虛擬 DOM

vDOM 類別與 #applyPatch() 仍在原始碼中,但目前渲染改用 replaceChildren() 整段替換以確保正確性,diff 與 patch 都沒有被呼叫。

EN