1 回答

TA貢獻(xiàn)1794條經(jīng)驗(yàn) 獲得超8個(gè)贊
constructor
永遠(yuǎn)無(wú)法創(chuàng)建在中設(shè)置 DOM 內(nèi)容的自定義元素document.createElement()
您將看到許多示例(包括我的示例),其中 DOM 內(nèi)容是在構(gòu)造函數(shù)中設(shè)置的。
這些元素永遠(yuǎn)無(wú)法創(chuàng)建document.createElement
說(shuō)明(HTML DOM API):
當(dāng)您使用時(shí):
<todo-card content=FOO></todo-card>
該元素(從 HTMLElement 擴(kuò)展)具有所有 HTML 接口(它在 HTML DOM 中),
您可以在構(gòu)造函數(shù)中設(shè)置 innerHTML
但是,當(dāng)你這樣做時(shí):
document.createElement("todo-card");
構(gòu)造函數(shù)在沒(méi)有 HTML 接口的情況下運(yùn)行(元素可能與 DOM 無(wú)關(guān)),因此在構(gòu)造函數(shù)
中設(shè)置 innerHTML會(huì)產(chǎn)生錯(cuò)誤:
未捕獲的 DOMException:無(wú)法構(gòu)造“CustomElement”:結(jié)果不得有子項(xiàng)
來(lái)自https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-conformance:
該元素不得獲得任何屬性或子元素,因?yàn)檫@違反了使用 createElement 或 createElementNS 方法的消費(fèi)者的期望。一般來(lái)說(shuō),工作應(yīng)該盡可能推遲到 connectedCallback
shadowDOM 是一個(gè) DOM
使用shadowDOM時(shí),您可以在構(gòu)造函數(shù)中設(shè)置shadowDOM內(nèi)容:
constructor(){
super().attachShadow({mode:"open"})
.innerHTML = `...`;
}
正確的代碼(沒(méi)有 shadowDOM):使用connectedCallback:
<todo-card content=FOO></todo-card>
<script>
window.customElements.define(
"todo-card",
class extends HTMLElement {
constructor() {
super();
//this.innerHTML = this.getAttribute("content");
}
connectedCallback() {
this.innerHTML = this.getAttribute("content");
}
}
);
try {
const todo = document.createElement("todo-card");
todo.setAttribute("content", "BAR");
document.body.appendChild(todo);
} catch (e) {
console.error(e);
}
</script>
您還有另一個(gè)小問(wèn)題:content
是默認(rèn)屬性,F(xiàn)ireFox 不會(huì)停止警告您:
或者不使用 createElement
const todo = document.createElement("todo-card");
todo.setAttribute("content", "BAR");
document.body.appendChild(todo);
可以寫成:
const html = `<todo-card content="BAR"></todo-card`;
document.body.insertAdjacentHTML("beforeend" , html);
可以connectedCallback運(yùn)行多次!
當(dāng)你四處移動(dòng) DOM 節(jié)點(diǎn)時(shí):
<div id=DO_Learn>
<b>DO Learn: </b><todo-card todo="Custom Elements API"></todo-card>
</div>
<div id="DONT_Learn">
<b>DON'T Learn!!! </b><todo-card todo="React"></todo-card>
</div>
<script>
window.customElements.define(
"todo-card",
class extends HTMLElement {
connectedCallback() {
let txt = this.getAttribute("todo");
this.append(txt);// and appended again on DOM moves
console.log("qqmp connectedCallback\t", this.parentNode.id, this.innerHTML);
}
disconnectedCallback() {
console.log("disconnectedCallback\t", this.parentNode.id , this.innerHTML);
}
}
);
const LIT = document.createElement("todo-card");
LIT.setAttribute("todo", "Lit");
DO_Learn.append(LIT);
DONT_Learn.append(LIT);
</script>
LIT 的 connectedCallback 運(yùn)行
移動(dòng) LIT 時(shí)
disconnectedCallback 運(yùn)行(注意父級(jí)!元素已經(jīng)在新位置)
LIT 的 connectedCallback 再次運(yùn)行,再次
"Learn Lit"
追加
這取決于你的程序員你的組件/應(yīng)用程序必須如何處理這個(gè)
Web 組件庫(kù)
像 Lit、HyperHTML 和 Hybrids 這樣的庫(kù)實(shí)現(xiàn)了額外的回調(diào)來(lái)幫助解決所有這些問(wèn)題。
我建議先學(xué)習(xí)自定義元素 API,否則你學(xué)習(xí)的是工具而不是技術(shù)。
有工具的傻瓜,仍然是傻瓜
添加回答
舉報(bào)