fix(core): fix gutter scroll desync with textarea content

- Match gutter font-size to textarea (13.5px) so line heights align
- Always sync gutter scrollTop regardless of mode
- Sync gutter scroll position after undo/redo history apply
This commit is contained in:
2026-07-24 11:20:47 +08:00
parent a70bfbf0cd
commit 5d9b934a2d
2 changed files with 10 additions and 4 deletions
+9 -3
View File
@@ -351,11 +351,15 @@ class MarkdownEditor {
ta.addEventListener('keyup', onCursorActivity); ta.addEventListener('keyup', onCursorActivity);
const onScroll = () => { const onScroll = () => {
// 同步行号滚动 // 同步行号滚动(始终同步,不限于分屏模式)
if (this.gutter) this.gutter.scrollTop = ta.scrollTop; if (this.gutter) {
this.gutter.scrollTop = ta.scrollTop;
}
// 同步预览滚动(仅分屏模式)
if (!this.config.syncScroll || this._mode !== 'split') return; if (!this.config.syncScroll || this._mode !== 'split') return;
const max = ta.scrollHeight - ta.clientHeight; const max = ta.scrollHeight - ta.clientHeight;
const ratio = max > 0 ? ta.scrollTop / max : 0; if (max <= 0) return;
const ratio = ta.scrollTop / max;
const pmax = this.previewPane.scrollHeight - this.previewPane.clientHeight; const pmax = this.previewPane.scrollHeight - this.previewPane.clientHeight;
this.previewPane.scrollTop = ratio * pmax; this.previewPane.scrollTop = ratio * pmax;
}; };
@@ -870,6 +874,8 @@ class MarkdownEditor {
this._render(); this._render();
this._renderGutter(); this._renderGutter();
this._updateWordCount(); this._updateWordCount();
// 同步行号滚动位置
if (this.gutter) this.gutter.scrollTop = this.textarea.scrollTop;
this._emit('change', this._value); this._emit('change', this._value);
if (typeof this.config.onChange === 'function') { if (typeof this.config.onChange === 'function') {
try { this.config.onChange(this._value, this); } catch (e) { console.error(e); } try { this.config.onChange(this._value, this); } catch (e) { console.error(e); }
+1 -1
View File
@@ -140,7 +140,7 @@ const generateCSS = () => {
border-right: 1px solid var(--md-border); border-right: 1px solid var(--md-border);
color: var(--md-muted); color: var(--md-muted);
font-family: var(--md-mono); font-family: var(--md-mono);
font-size: 12px; font-size: 13.5px;
line-height: 1.7; line-height: 1.7;
text-align: right; text-align: right;
user-select: none; user-select: none;