问题描述
我正在寻找一种不重用 lit-html/lit-element 中的 DOM 元素的方法(是的,我知道,我正在关闭其中一个主要功能)。特定场景是将现有系统移动到 lit-element/lit-html,在某些点嵌入 trumowyg WYSIWYG 编辑器。这个编辑器将自己附加到一个在 lit-element 中创建的 <div>
标签并修改它自己的内部 DOM,但当然 lit-html 不知道这已经发生了,所以它经常会重用相同的 <div>
标签而不是创建一个新标签。我正在寻找类似于 vue.js
键属性(例如,preventing Vue from aggresively reusing dom-elements)
我觉得 live()
中的 lit-html
指令应该对此有用,但它可以防止基于给定属性的重用,即使所有属性都相同,我也想防止重用。谢谢!
解决方法
我在富文本编辑器和 contenteditable
方面遇到过类似问题 - 由于模板更新 DOM 的方式,您不希望它成为模板的一部分。
您可以通过添加一个具有非 Lit DOM 的新元素,然后将那个添加到 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);
由于这是在自定义元素的 shadow DOM Lit 中运行,因此不会触及它,您可以这样做:
html`
<div>Lit managed DOM</div>
<trumbowyg-editor></trumbowyg-editor>`;
但是,您必须在 TrumbowygEditor
上实现属性和事件,以添加要传递给嵌套 jQuery 组件或从嵌套 jQuery 组件获取的所有内容。
如果您可以获得 jQuery/Trumbowyg 的模块版本(或您的构建工具支持它),您可以使用 import
添加脚本,或者您可以向组件添加 <script>
标签,添加回退加载 DOM constructor
中的内容,然后在 <script>
的加载事件上调用 $(div).trumbowyg()
来初始化组件。
虽然更麻烦和更多工作,但我建议使用后者,因为这两个组件都很大并且(由于 jQuery 建立在现在 15 岁的假设上)需要同步加载(<script async
或 {{1} } 不工作)。尤其是在较慢的连接上,Lit 会在 jQuery/Trumbowyg 加载之前很久就准备好了,所以你希望 <script defer
在发生这种情况时看起来不错(显示微调器、布局在适当的空间等)。
您写道,您将外部库直接附加到由 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)