自定义 HTML 标签如何与克隆模板交互?

问题描述 投票:0回答:1

这是我感到困惑的测试用例。在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
值,以及为什么我的示例会如此?

javascript typescript custom-element html-templates
1个回答
0
投票

类对象和附加到 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>

© www.soinside.com 2019 - 2024. All rights reserved.