如何在GreaseMonkey脚本中获取Monaco Editor实例?
获取GreaseMonkey脚本中Monaco Editor实例的可靠方法
核心问题分析
你遇到的问题本质是:Monaco Editor在很多页面中不会把monaco对象暴露到全局window上(比如用ES模块加载时),且实例也不会挂载到document或标准全局位置,导致GreaseMonkey脚本的隔离环境无法直接访问。
两种可靠解决方案
方案1:尝试通过全局环境获取(适用于monaco全局暴露的场景)
GreaseMonkey提供的unsafeWindow对象可以直接访问页面的全局变量空间。如果页面的monaco对象存在于全局,就能用这种方法快速获取所有编辑器实例:
// ==UserScript== // @name 抓取Monaco内容 // @match *://*/* // @grant unsafeWindow // ==/UserScript== (function() { 'use strict'; // 从页面全局获取monaco对象 const monaco = unsafeWindow.monaco; if (!monaco?.editor) return; // 获取所有编辑器实例 const editors = monaco.editor.getEditors(); editors.forEach((editor, index) => { const content = editor.getValue(); console.log(`第${index+1}个Monaco编辑器内容:`, content); // 这里可以添加你的后续操作,比如保存内容等 }); })();
方案2:通过DOM容器绑定的实例获取(通用可靠方案)
绝大多数新版本Monaco Editor会把实例绑定到编辑器的DOM容器元素的__monaco_editor__属性上,不管monaco是否全局暴露,都能通过这种方法拿到实例:
// ==UserScript== // @name 抓取Monaco内容 // @match *://*/* // @grant none // ==/UserScript== (function() { 'use strict'; // 查找所有Monaco编辑器的DOM容器(类名通常是monaco-editor) const editorContainers = document.querySelectorAll('.monaco-editor'); if (editorContainers.length === 0) return; editorContainers.forEach((container, index) => { // 从容器获取绑定的编辑器实例 const editor = container.__monaco_editor__; if (!editor) return; const content = editor.getValue(); console.log(`第${index+1}个Monaco编辑器内容:`, content); }); })();
注:如果页面的Monaco容器类名不是
monaco-editor,可以通过检查DOM结构找特征(比如容器内有.monaco-editor-background等子元素)。
针对你的示例页面(CoderPad Sandbox)的测试
在目标测试页面中,用方案2可以直接拿到编辑器实例:容器类名是monaco-editor,且__monaco_editor__属性存在,调用getValue()就能获取代码内容。
为什么控制台执行monaco.editor.getEditors()会报错?
因为该页面用ES模块加载Monaco,monaco对象被封装在模块作用域内,没有挂载到全局window上,所以直接在控制台访问不到。而GreaseMonkey的unsafeWindow可以突破模块作用域限制访问页面全局,但如果页面完全隔离了模块变量,方案2就是更稳妥的选择。
内容的提问来源于stack exchange,提问作者Robert Thyssel
相关产品推荐
相关产品推荐

