我创建了一个自定义 HTML 元素,它从以下模板创建一个新元素:
<template id="track">
<div class="record">Nothing yet</div>
</template>
这里是定义自定义元素的JS代码:
class Track extends HTMLElement {
constructor() {
super();
this.template = document.getElementById("track");
this.clone = this.template.content.cloneNode(true);
}
connectedCallback() {
this.append( this.clone );
}
set record(html) {
// Case 1: Works only for element 1 (before appending to the DOM)
this.clone.querySelector('.record').innerHTML = html;
// Case 2: Works only for element 2 (after appending to the DOM)
//this.querySelector('.record').innerHTML = html;
}
}
customElements.define('my-track', Track);
请注意更改
<div>
的 HTML 内容的记录属性。我希望能够更新元素内容,无论它是否已附加到 DOM。我无法编写在这两种情况下都有效的代码(在将自定义元素附加到 DOM 之前和之后)。以下代码仅适用于情况 1:
const el1 = document.createElement('my-track');
el1.record = "Bla<b>bla</b> #1";
document.body.append(el1);
以下代码仅适用于情况2
const el2 = document.createElement('my-track');
document.body.append(el2);
el2.record = "Bla<b>bla</b> #2";
当然,在方法
set record()
中,我可以检查元素是否已经附加到DOM并相应地切换到情况1或情况2。但我觉得这不是构建自定义元素的正确方法。
在方法中更新元素内容的最佳选项是什么
set record()
无论元素是否已附加到 DOM?
我在这里创建一个 JSFiddle:https://jsfiddle.net/Alphonsio/gL8a239o/13/
当没有 DOM 时,你无法向 DOM 写入任何内容。
就像还没有房子的时候,你不能在客厅放沙发一样。
这意味着您必须在
this.isConnected
方法中使用 set record
检查该元素是否附加到 DOM。
它是 JavaScript 类/对象的实例;您当然可以将任何您想要的东西附加到它并让
constructor/attributeChangedCallback/connectedCallback
处理它(但要仔细考虑房子/客厅的场景)
const createElement = (tag, props = {}) => Object.assign(document.createElement(tag), props);
customElements.define('my-track', class extends HTMLElement {
connectedCallback() {
this.append(
this.recordDIV = createElement("div", {
innerHTML: `Default Record content`
}))
}
set record(html) {
if (this.isConnected)
this.recordDIV.innerHTML = html;
else
console.warn(this.id, "Not in the DOM yet")
}
});
const el1 = createElement('my-track', {
id: "el1"
});
el1.record = "Record #1";
document.body.append(el1);
const el2 = createElement('my-track', {
id: "el2"
});
document.body.append(el2);
el2.record = "Record #2";