如何实现Monaco Editor垂直滚动条与高度不同的div同步滚动
Monaco Editor 0.27.0 垂直滚动同步优化方案
你代码中的168是用来修正「用窗口高度代替编辑器可视高度」的误差值,本质是硬编码的魔法数,可通过Monaco自带的API获取编辑器真实布局属性来实现更规范的同步逻辑,代码如下:
// 提前缓存目标DOM,避免滚动时重复查询 const targetEl = document.getElementById('html-out'); window.editor.onDidScrollChange(function (e) { // 仅滚动位置变化时处理 if (!e.scrollTopChanged) return; // 获取编辑器可视区域高度,替代原逻辑中的窗口高度 const editorVisibleHeight = window.editor.getLayoutInfo().height; // 计算编辑器最大可滚动距离 const editorMaxScroll = e.scrollHeight - editorVisibleHeight; // 编辑器内容不足一屏时无需同步 if (editorMaxScroll <= 0) return; // 计算滚动占比,无硬编码值适配所有布局 const scrollPercentage = e.scrollTop / editorMaxScroll; // 计算目标容器的最大可滚动距离 const targetMaxScroll = targetEl.scrollHeight - targetEl.offsetHeight; // 赋值滚动位置,添加边界判断避免数值溢出 targetEl.scrollTop = Math.max(0, Math.min(targetMaxScroll, scrollPercentage * targetMaxScroll)); });
核心调整说明
- 移除硬编码的168修正值:通过Monaco Editor实例内置的
getLayoutInfo()接口直接获取编辑器自身的可视高度,完全匹配实际布局,不需要手动校准数值 - 增加异常边界处理:避免编辑器或目标容器内容不足一屏时,出现除以0导致的计算错误、滚动位置错位问题
- 优化性能表现:将目标DOM的查询逻辑提到滚动事件外,减少高频触发的滚动事件中的DOM操作开销
可选双向同步逻辑
如果需要实现拖动div滚动条反向同步到编辑器,可补充如下代码:
targetEl.addEventListener('scroll', function() { const targetMaxScroll = this.scrollHeight - this.offsetHeight; if (targetMaxScroll <= 0) return; const percentage = this.scrollTop / targetMaxScroll; const editorMaxScroll = window.editor.getScrollHeight() - window.editor.getLayoutInfo().height; window.editor.setScrollPosition({ scrollTop: Math.max(0, Math.min(editorMaxScroll, percentage * editorMaxScroll)) }); }, { passive: true });
内容的提问来源于stack exchange,提问作者Prashant
相关产品推荐
相关产品推荐

