在 Monaco Editor 中实现自定义按钮与引用内容的四种方法详解
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:主要用于样式装饰
