这是我感到困惑的测试用例。在html中(在
body
的末尾):
<template id="test">
<test-tag class="test-id"></test-tag>
</template>
在脚本中:
class TestTag extends HTMLElement {
constructor() {
super();
console.log("TestTag created");
}
get Property() : string {
return "Hello";
}
}
// in some function:
customElements.define("test-tag", TestTag);
customElements.whenDefined("test-tag").then(() => {
console.log("test-tag defined");
var tag = document.createElement("test-tag") as TestTag;
console.log(tag.Property);
var template = document.getElementById("test") as HTMLTemplateElement;
var clone = template.content.cloneNode(true) as DocumentFragment;
var tag2 = clone.querySelector<TestTag>(".test-id");
if(tag2 == null){
console.error("tag2 is null");
} else {
//customElements.upgrade(tag2);
if(!(tag2 instanceof TestTag)){
console.error("WTF?!"); //did not expect to be here
}
console.log(tag2.Property); //tag2.Property is undefined
}
});
第一个
tag
对象按我的预期工作。第二个则不然:克隆模板似乎会创建一个通用 DOM 元素,而不是我的 TestTag
类的实例。
对我来说,这似乎是自定义元素的主要功能 - 定义必要的行为并重用它,同时仍然使用 HTML 标记描述复杂的 div,而不是一些丑陋的数十个
createElement
/appendChild
调用的构造代码。所以看来我错过了一些明显的东西。就像影子 DOM 机制一样,但 customElements.upgrade()
在这种情况下什么也不做。
我的问题是:如果我错过了使用自定义元素的一些众所周知的部分,那么它是什么?如果不是,可以合理地采取什么措施来获取
TestTag
实例作为上面示例中的 tag2
值,以及为什么我的示例会如此?
类对象和附加到 DOM 的DOM 元素之间存在差异
<template id="test">
<test-tag class="test-id"></test-tag>
</template>
<script>
class TestTag extends HTMLElement {
get Property() {
return "Hello";
}
}
customElements.define("test-tag", TestTag);
var tag = document.createElement("test-tag");
var template = document.getElementById("test");
var clone = template.content.cloneNode(true);
var tag2 = clone.querySelector(".test-id");
console.log(tag2.nodeName, tag2.constructor.name, tag2 instanceof HTMLElement, tag2 instanceof TestTag, tag2.Property);
document.body.append(tag2); // MAKE IT DOM!!!
console.log(tag2.nodeName, tag2.constructor.name, tag2 instanceof HTMLElement, tag2 instanceof TestTag, tag2.Property);
</script>