防止 DOM 在 lit-html/lit-element 内重复使用

Prevent DOM reuse within lit-html/lit-element

我正在寻找一种不重用 lit-html/lit-element 中的 DOM 元素的方法(是的,我知道,我正在关闭其中一个主要功能)。特定情况是将现有系统移动到 lit-element/lit-html,该系统在某些点嵌入了 trumbowyg 所见即所得编辑器。这个编辑器将自己附加到一个在 lit-element 中制作的 <div> 标签,并修改它自己的内部 DOM,但是 lit-html 当然不知道这已经发生了,所以它经常会重用相同的 <div> 标签而不是创建新标签。我正在寻找类似于 vue.js 键属性的东西(例如,

我觉得 lit-html 中的 live() 指令应该对此有用,但它可以防止基于给定属性的重用,即使所有属性都相同,我也想防止重用.谢谢!

我在使用富文本编辑器和 contenteditable 时遇到了类似的问题 - 由于模板更新 DOM 的方式,您不希望它成为模板的一部分。

您可以通过添加一个带有非 Lit DOM 的新元素,然后将 that 添加到 Lit 管理的 DOM 来实现:

class TrumbowygEditor
  extends HTMLElement {

  constructor() {
    super();
    const shadow = this.attachShadow({mode: 'open'});
    const div = document.createElement('div');
    shadow.appendChild(div);
    
    const style = document.createElement('style');
    // Add CSS required 
    shadow.appendChild(style);

    $(div).trumbowyg(); //init
  }
}

customElements.define('trumbowyg-editor', TrumbowygEditor);

因为这是 运行 在自定义元素的阴影中 DOM Lit 不会碰它,你可以这样做:

html`
    <div>Lit managed DOM</div>
    <trumbowyg-editor></trumbowyg-editor>`;

但是,您必须在 TrumbowygEditor 上实现属性和事件,以添加您想要传递给嵌套的 jQuery 组件或从嵌套的 jQuery 组件获取的所有内容。

如果您可以获得 jQuery/Trumbowyg 的模块版本(或者您的构建工具支持它),您可以使用 import 添加脚本,或者您可以将 <script> 标记添加到您的组件,在 constructor 中添加后备加载 DOM 内容,然后在 <script> 的加载事件上调用 $(div).trumbowyg() 来初始化组件。

虽然更混乱和更多的工作,但我推荐后者,因为这两个组件都很大并且(由于 jQuery 建立在现在 15 岁的假设之上)需要同步加载(<script async<script defer 不起作用)。特别是在较慢的连接上 Lit 会在 jQuery/Trumbowyg 加载之前很久就准备好,所以你希望 <trumbowyg-editor> 看起来不错(显示微调器,适当数量的 space 等布局) .

您写道,您将外部库直接附加到由 lit-html 管理的元素。听起来你基本上是这样做的:

render(html`<section><div id=target></div></section>`, document.body)
external_lib.render_to(document.querySelector("#target"))

如果这是您要做的,请尝试创建您自己的 div,让外部库渲染到 div,最后将 div 附加到 lit-html:

let target_div = document.createElement('div')
render(html`<section>${div}</section>`, document.body)
external_lib.render_to(target_div)