You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现两个Monaco编辑器之间的行高度视觉匹配?

实现两个Monaco编辑器行高同步匹配的方案

核心逻辑和官方diff模式的实现思路一致,通过同步每一行的实际渲染高度即可实现,具体操作步骤如下:

  • 第一步:统一编辑器基础排版配置
    首先要保证两个编辑器的基础排版参数完全对齐,避免出现基础行高偏差:
const sharedConfig = {
  lineHeight: 20, // 固定基础单行行高
  wordWrap: 'on', // 折行规则保持一致,也可按业务需求单独配置,不影响行高同步逻辑
  fontSize: 14,
  fontFamily: 'Consolas, "Courier New", monospace',
  scrollBeyondLastLine: false,
  // 其他会影响行排版的参数都要统一,比如行内边距、字重等
}
const editorA = monaco.editor.create(document.getElementById('editor-a'), sharedConfig)
const editorB = monaco.editor.create(document.getElementById('editor-b'), sharedConfig)
  • 第二步:实现行高同步核心函数
    使用Monaco官方提供的changeViewZonesAPI(diff编辑器同步行高的核心接口),给高度不足的行插入对应的空白填充区域,强制行高对齐:
function syncLineHeights(sourceEditor, targetEditor) {
  const maxSyncLine = Math.min(sourceEditor.getModel().getLineCount(), targetEditor.getModel().getLineCount())
  const fillZones = []

  for (let line = 1; line <= maxSyncLine; line++) {
    // 取源编辑器当前行的实际渲染高度(包含折行后的总高度)
    const sourceActualHeight = sourceEditor.getLineHeight(line)
    // 取目标编辑器当前行的原生高度
    const targetActualHeight = targetEditor.getLineHeight(line)

    // 高度不一致时计算差值,插入填充区域
    if (sourceActualHeight > targetActualHeight) {
      const diff = sourceActualHeight - targetActualHeight
      fillZones.push({
        afterLineNumber: line - 1,
        heightInPx: diff,
        domNode: document.createElement('div'),
        suppressMouseDown: true
      })
    }
  }

  // 替换目标编辑器的所有填充区域,避免重复添加
  targetEditor.changeViewZones(accessor => {
    accessor.clear()
    fillZones.forEach(zone => accessor.addZone(zone))
  })
}
  • 第三步:绑定同步触发事件
    所有会导致行高变化的场景都要触发双向同步:
const biDirectionSync = () => {
  syncLineHeights(editorA, editorB)
  syncLineHeights(editorB, editorA)
}

// 内容变更时同步
editorA.onDidChangeModelContent(biDirectionSync)
editorB.onDidChangeModelContent(biDirectionSync)

// 编辑器尺寸变化时同步
editorA.onDidLayoutChange(biDirectionSync)
editorB.onDidLayoutChange(biDirectionSync)

// 配置变更(比如修改折行规则、字号)时同步
editorA.onDidChangeConfiguration(biDirectionSync)
editorB.onDidChangeConfiguration(biDirectionSync)

// 初始化执行一次
biDirectionSync()

如果两个编辑器的行数不一致,可以按业务需求处理超出部分:比如给行数更少的编辑器末尾插入对应高度的空白填充,或者截断超出行数的同步逻辑即可。
对性能要求高的场景,可以监听onDidChangeViewZones事件做防抖处理,减少重复渲染次数。

内容的提问来源于stack exchange,提问作者qz-

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 08:06:03