← 全部文档

Shadow DOM

让编辑器在 shadow root 中运行,例如在您自己的 Web 组件或微前端中。页面样式表不会作用到 shadow root 内部,因此如果没有辅助,其中的编辑器将没有样式;这个插件会把编辑器自己的样式表复制到包含它的 shadow root 中,并持续复制插件之后添加的样式表。

位于自定义元素 shadow root 中的编辑器,带有已设置样式的工具栏,旁边打开了 Insert Link 对话框,显示 URL 和 Text 字段、Open in new tab、Cancel 和 Insert
在自定义元素的 shadow root 中创建的编辑器,打开了 Insert Link 对话框。两者都有样式。

启用

该功能由 shadowdom.js 插件提供(也包含在 plugins/all_plugins.js 中)。像平常一样在页面中加载编辑器的样式表,然后在 shadow root 内的某个元素上创建编辑器;其余的由插件完成。它没有按钮。

<link rel="stylesheet" href="/richtexteditor/rte_theme_default.css">
<script src="/richtexteditor/rte.js"></script>
<script src="/richtexteditor/plugins/all_plugins.js"></script>

<note-editor id="host"></note-editor>
<script>
class NoteEditor extends HTMLElement {
  connectedCallback() {
    const root = this.attachShadow({ mode: "open" });
    root.innerHTML = '<div class="box"><p>Text inside a <b>shadow root</b>.</p></div>';
    this.editor = new RichTextEditor(root.querySelector(".box"), { toolbar: "basic", height: "220px" });
  }
}
customElements.define("note-editor", NoteEditor);
</script>

rte-webcomponent.js 中现成的 <rich-text-editor> 元素使用的也是这个插件:添加 shadow 属性,它就会把编辑器挂载到自己的 shadow root 中。

<script src="/richtexteditor/rte-webcomponent.js"></script>
<rich-text-editor shadow toolbar="basic" height="220px"><p>Hello</p></rich-text-editor>

如果没有加载 shadowdom.js,该元素会在控制台中输出一条警告,并留在 light DOM 中,而不会以无样式的状态渲染。

选项

选项默认值作用
shadowStyleAdoptiontrue把编辑器的样式表复制到 shadow root 中。false 会关闭复制。
shadowStyleSourcesnull要添加到 shadow root 中的额外样式表 URL,可以是字符串或数组,用于您自己的皮肤覆盖样式。

复制哪些内容

  • 从加载 rte.js 的文件夹提供的 <link rel="stylesheet"> 元素,或者文件名属于编辑器的元素(rte_theme、rte_mobile、richtexteditor_content、richtexteditor_preview、aitoolkit)。它们会以相同的 URL 重新创建为新的 <link> 元素,因此会从浏览器缓存中加载。
  • id 以 rte- 或 __rte 开头的 <style> 元素(插件的样式),以及没有 id、但 CSS 中提到编辑器选择器的 <style> 元素——Vite 等打包工具就是以这种方式注入导入的主题的。
  • 页面通过 document.adoptedStyleSheets 采用的样式表。

页面中的其他内容都不会被复制,因此您的组件仍然保持封装。每个副本都带有 data-rte-adopted="1"。在上面的测试页面中,复制了 9 个样式表(主题、AI Toolkit 样式表以及插件的 <style> 元素),工具栏高度为 41 像素。设置 shadowStyleAdoption: false 时,工具栏高度为 7,561 像素,变成了一列没有样式的按钮。

插件会监视页面的 <head>,因此启动之后、插件面板首次打开时才添加的插件样式也会被复制。对话框和菜单在编辑器的元素内部创建,因此它们位于 shadow root 中,并使用复制过来的样式。

API

  • editor.isInShadowDom()——编辑器位于 shadow root 中时为 true。
  • editor.getShadowRoot()——该 shadow root,或者 null。
  • editor.getAdoptedStyleCount()——已复制的样式表数量(上例中为 9)。
  • editor.adoptEditorStyles(target)——把编辑器的样式表复制到另一个根中,例如用于显示预览的第二个 shadow root。不带参数时,使用编辑器自己的 shadow root。

注意事项

  • 编辑区域是一个 iframe,因此文档自身的 CSS 会照常加载到其中(contentCssUrl);这个插件只与编辑器的工具栏、菜单和对话框有关。
  • 在 shadow root 之外,插件不做任何事,也不会创建观察器。
  • 写在页面样式表中、用于覆盖编辑器外观的样式,不会作用到 shadow root 内部。请把它们列在 shadowStyleSources 中,或者自己把它们放进 shadow root。
  • 保存的 HTML 不受影响;getHTMLCode() 返回了 <p>Text inside a <b>shadow root</b>.</p>。

相关内容:快速入门、表单验证。