改版通知

巨人肩膀网站已全新改版。若您仍依赖旧站功能或数据,欢迎联系我们,我们会协助处理。联系我们

在 Monaco Editor 中实现自定义按钮与引用内容的四种方法详解

梦想家 创建于 2025年11月21日502

Monaco Editor 支持在内容区域显示自定义按钮或引用内容。主要方式如下:

1. ContentWidget(内容小部件)

在特定位置(基于行号和列号)添加自定义 DOM 元素,可包含按钮或引用内容。

javascript 复制代码
class MyContentWidget {
  constructor(editor, lineNumber, column) {
    this.editor = editor;
    this.lineNumber = lineNumber;
    this.column = column;
    this.domNode = null;
  }

  getId() {
    return 'my.content.widget';
  }

  getDomNode() {
    if (!this.domNode) {
      this.domNode = document.createElement('div');
      this.domNode.innerHTML = `
        <button class="custom-btn">自定义按钮</button>
        <div class="reference-content">引用内容</div>
      `;
      this.domNode.style.backgroundColor = '#fff';
      this.domNode.style.border = '1px solid #ccc';
      this.domNode.style.padding = '8px';
    }
    return this.domNode;
  }

  getPosition() {
    return {
      position: {
        lineNumber: this.lineNumber,
        column: this.column
      },
      preference: [
        monaco.editor.ContentWidgetPositionPreference.BELOW,
        monaco.editor.ContentWidgetPositionPreference.ABOVE
      ]
    };
  }
}

// 使用方式
const widget = new MyContentWidget(editor, 5, 1);
editor.addContentWidget(widget);

2. OverlayWidget(覆盖层小部件)

在编辑器上添加固定位置的覆盖层,适合工具栏或固定按钮。

javascript 复制代码
class MyOverlayWidget {
  constructor(editor) {
    this.editor = editor;
    this.domNode = null;
  }

  getId() {
    return 'my.overlay.widget';
  }

  getDomNode() {
    if (!this.domNode) {
      this.domNode = document.createElement('div');
      this.domNode.innerHTML = '<button>固定按钮</button>';
      this.domNode.style.position = 'absolute';
      this.domNode.style.top = '10px';
      this.domNode.style.right = '10px';
    }
    return this.domNode;
  }

  getPosition() {
    return {
      preference: [
        monaco.editor.OverlayWidgetPositionPreference.TOP_RIGHT_CORNER
      ]
    };
  }
}

// 使用方式
const overlayWidget = new MyOverlayWidget(editor);
editor.addOverlayWidget(overlayWidget);

3. ViewZone(视图区域)

在行之间插入自定义视图区域,适合插入较大的自定义内容块。

javascript 复制代码
let viewZoneId = null;

const viewZone = {
  afterLineNumber: 5, // 在第5行之后插入
  heightInPx: 100, // 高度
  domNode: document.createElement('div')
};

viewZone.domNode.innerHTML = `
  <div style="padding: 10px; background: #f5f5f5;">
    <button>视图区域按钮</button>
    <p>这是引用内容</p>
  </div>
`;

viewZoneId = editor.changeViewZones((changeAccessor) => {
  changeAccessor.addZone(viewZone);
});

4. Decorations(装饰器)

用于样式装饰,可配合其他方式使用。

javascript 复制代码
const decoration = {
  range: new monaco.Range(5, 1, 5, 10),
  options: {
    isWholeLine: false,
    className: 'my-custom-decoration',
    glyphMarginClassName: 'my-glyph-margin',
    hoverMessage: { value: '这是一个自定义装饰' }
  }
};

const decorationIds = editor.deltaDecorations([], [decoration]);

总结

  • ContentWidget:适合在代码特定位置显示按钮或引用
  • OverlayWidget:适合固定位置的工具栏或按钮
  • ViewZone:适合在行间插入较大的自定义内容块
  • Decorations:主要用于样式装饰