document.scripts无法管理编辑器插件,因其只读且仅反映已解析的script标签;插件是否生效取决于编辑器内部注册表,应通过插件api、事件或模块加载结果判断。

Document.scripts 无法直接管理编辑器插件
Document.scripts 是只读的 HTMLCollection,它只反映当前文档中已存在(且已解析)的 <script></script> 元素,不包含动态插入后尚未执行的脚本节点,更不会跟踪编辑器内部通过 eval、import() 或 API 注入的逻辑。很多 HTML 编辑器(如 Monaco、CodeMirror 6)根本不在主文档 DOM 中创建 <script></script> 标签——它们用模块加载器或 worker 加载插件代码,此时 Document.scripts 完全不可见。
真正要管的是编辑器自身的插件注册表
编辑器插件是否生效,取决于其内部插件系统是否完成注册和激活,而非脚本标签是否存在。比如:
- TinyMCE:靠
tinymce.PluginManager.add()注册,靠editor.plugins.<name></name>判断是否加载成功 - Monaco Editor:插件通过
monaco.editor.registerCommand()或monaco.languages.registerCompletionItemProvider()注入,状态查monaco.editor.getLanguages() - CodeMirror 6:插件是 Extension 对象,由
EditorView.constructor({ extensions })组合,运行时无全局脚本痕迹
你试图用 Document.scripts 去“等待某个插件脚本加载完毕”,实际可能根本没对应项;而插件已就绪,但 Document.scripts 里早没了它的 <script></script> 节点(已被移除或从未插入)。
怎么可靠判断插件是否可用
别依赖 DOM 脚本列表,改查编辑器实例提供的运行时接口:
- 检查插件是否在编辑器配置中声明(如 TinyMCE 的
plugins: ['myplugin']) - 调用插件暴露的 API 是否存在,例如
editor.execCommand('myCustomCmd')或editor.myPlugin?.init() - 监听编辑器的
init或PluginLoaded事件(TinyMCE 有PluginLoad),而非load事件 - 对异步加载的插件模块,用
import('./my-plugin.js').then(m => m.install(editor))显式控制时机
若插件通过 <script src="plugin.js"></script> 引入,且你必须等它,应监听该脚本的 onload,或检查其挂载的全局变量(如 window.MyPluginLoader),而不是轮询 Document.scripts。
常见误操作与后果
以下写法看似合理,实则脆弱或无效:
-
while (Document.scripts.length === 0) {}—— 死循环,阻塞主线程,且Document.scripts不随动态插入实时更新(需 reflow 才刷新) -
Array.from(Document.scripts).some(s => s.src.includes('my-plugin'))—— 外部插件可能被打包合并,src 不匹配;内联插件无 src;CDN 地址带版本号或 hash,难以稳定识别 - 在
DOMContentLoaded后立即遍历Document.scripts查插件 —— 此时插件 JS 可能还没下载完,更别说执行注册逻辑
插件加载的不确定性主要来自执行时序与注册入口分离——脚本加载完成 ≠ 插件注册完成 ≠ 编辑器实例可调用。最稳妥的方式,是让插件自己报告就绪状态,而不是从 DOM 树里“找证据”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











