Rendering and Sync
This page explains when MDViewer re-renders, what a render does, and how scroll sync with the editor works.
Triggers
| Source | Condition |
|---|---|
Editor keyup |
autosave is truthy and the key is not an arrow key, Shift, Control, Alt, CapsLock, Escape, F1-F12 or Meta |
Editor formatting methods (bold(), heading(), ...) |
autosave is truthy |
undo(), redo() |
autosave is truthy |
clear(), openfile() once the file is read |
Always |
save() |
When autosave is false (Cmd/Ctrl+S or the toolbar "save and preview" button) |
Calling viewer.init(text) directly |
Always |
With autosave: false, typing is not reflected in the preview; only save() updates it.
Render Steps
What viewer.init(txt) does:
- Sets
data-saved="1"and clears the previous timer - Waits
sync.delaymilliseconds (300 by default; passing0falls back to 300 because it is falsy) - Picks the content: the first non-empty of
txt, the bound editor's text,emptyContent - Calls
transToHTML()(extended mode, with the hashtag settings) - Replaces the viewer content wholesale with
replaceChildren() - Binds every code block's copy button to
navigator.clipboard.writeText(); adds thesuccessclass for 1 second on success, theerrorclass on failure - Polls every 50 ms until code-prettify's global
PRexists; then restores the scroll position, runsPR.prettyPrint(), and runsmermaid.run()on every.mermaidelement in the document
Continuous typing keeps resetting the timer, so a render only happens after input pauses for longer than sync.delay (debounce).
Reading Editor Text
The viewer does not receive data through events; at render time it reads the innerText of every <div> row in the editor container. Blank rows become a single \n, non-breaking spaces become plain spaces, and the whole result is trimmed.
Scroll Sync
With sync.scroll truthy, binding the editor sets the editor's onwheel: each wheel event adds deltaY to the viewer's scrollTop.
| Limitation | Detail |
|---|---|
| Wheel only | Dragging the scrollbar, touch swipes and keyboard scrolling are not synced |
| One-way | Only the editor drives the viewer |
| Delta-based | Not proportional; positions drift when the two sides differ greatly in height |
Overwrites onwheel |
Replaces any existing onwheel handler on the editor container |
Saved-State Flag
The data-saved attribute on the editor and viewer containers tracks whether content is in sync: input sets it to 0 (unsave()), the start of a render sets it to 1. NanoMD.css styles this state, and you can use it for a custom "unsaved" indicator.
Virtual DOM
The vDOM class and #applyPatch() are still in the source, but rendering currently uses a wholesale replaceChildren() for correctness; neither diff nor patch is called.