gpt4 book ai didi

javascript - 如何将 TEMPLATE 元素附加到 shadow dom?

转载 作者:行者123 更新时间:2023-12-05 00:36:44 25 4
gpt4 key购买 nike

当我尝试将模板附加到影子 DOM 时,它仅显示为“#documentFragment”,并且从不呈现或复制模板中结构的实际元素。
我花了几个小时试图弄清楚。我找到的解决方案是使用:

  • template.firstElementChild.cloneNode(true);

  • 代替:
  • 模板.content.cloneNode(true);

  • 然后,只有这样,一切都会按预期工作。
    我的问题是,我做错了吗?

    const template = document.createElement('template');
    const form = document.createElement('form');
    const gateway = document.createElement('fieldset');
    const legend = document.createElement('legend');
    gateway.appendChild(legend);
    const username = document.createElement('input');
    username.setAttribute('type', 'email');
    username.setAttribute('name', 'username');
    username.setAttribute('placeholder', 'email@address.com');
    username.setAttribute('id', 'username');
    gateway.appendChild(username);
    const button = document.createElement('button');
    button.setAttribute('type', 'button');
    button.innerHTML = 'Next';
    gateway.appendChild(button);
    form.appendChild(gateway);
    template.appendChild(form);
    class UserAccount extends HTMLElement {
    constructor() {
    super();
    const shadowDOM = this.attachShadow({
    mode: 'open'
    });
    const clone = template.firstElementChild.cloneNode(true);
    // This does not work
    // const clone = template.content.cloneNode(true);
    shadowDOM.appendChild(clone);
    shadowDOM.querySelector('legend').innerHTML = this.getAttribute('api');
    }
    }
    window.customElements.define('user-account', UserAccount);
    <!DOCTYPE html>
    <html lang="en">

    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">

    <!-- <link rel="stylesheet" href="./css/main.css"> -->
    <script src="./js/user-account.js" defer></script>
    <title>Title</title>
    </head>

    <body>

    <user-account api="/accounts"></user-account>

    </body>

    </html>

    最佳答案

    TEMPLATES仅当您需要制作多个副本或希望尽可能使用纯 HTML + CSS 时才有意义。
    许多 Web 组件显示了用法:

    const template = document.createElement("template");
    template.innerHTML = "Hello World"
    然后做:
    constructor() {
    super();
    this._shadowRoot = this.attachShadow({ mode: "open" });
    this._shadowRoot.appendChild(template.content.cloneNode(true));
    }
    其中,因为模板仅用作单个“父”容器,您可以写成:
    constructor() {
    super().attachShadow({ mode: "open" }).innerHTML = "Hello World";
    }
    注: super()返回 this , 和 attachShadow()设置并返回 this.shadowRoot ... 免费
    两种类型的模板
    您可以创建 <TEMPLATE> DOM ,或者您可以创建一个 template内存
    内存中的模板
    10 个中有 9 个 内存模板 可以用其他 HTMLElements 作为容器来完成,
    与您的代码一样,其中 FORM可以是主容器。无需 template容器。
    如果您确实在内存中构建了模板,请了解 append() 的值超过
    (经常被误用) appendChild()
    In Memory 模板非常适合进行(许多)更改(使用代码)
    DOM 中的模板
    无需尝试填充 HTML CSS 在 JavaScript 字符串中,您在 HTML 文档中有一个 DOM!
    使用 <TEMPLATE> HTML 元素。
    添加 shadowDOM <slot> 混合起来,您将花费更少的时间来调试 JavaScript,而将更多的时间用于编写语义 HTML。
    DOM 模板非常适合对更多静态 HTML/CSS 结构进行简单的 HTML 和 CSS 编辑(在您的 IDE 中使用语法高亮显示)

    这是您的代码的两种类型的模板,哪一种对开发人员来说更容易?

      const form = document.createElement('form');
    const gateway = document.createElement('fieldset');
    const legend = document.createElement('legend');
    const username = document.createElement('input');
    username.setAttribute('type', 'email');
    username.setAttribute('name', 'username');
    username.setAttribute('placeholder', 'email@address.com');
    username.setAttribute('id', 'username');
    const button = document.createElement('button');
    button.setAttribute('type', 'button');
    button.innerHTML = 'Next';
    gateway.append(legend,username,button);
    form.appendChild(gateway);

    class Form extends HTMLElement {
    constructor(element) {
    super().attachShadow({mode:'open'}).append(element);
    }
    connectedCallback() {
    this.shadowRoot.querySelector('legend').innerHTML = this.getAttribute('api');
    }
    }

    window.customElements.define('form-one', class extends Form {
    constructor() {
    super(form)
    }
    });
    window.customElements.define('form-two', class extends Form {
    constructor() {
    super(document.getElementById("FormTwo").content);
    }
    });
    <template id="FormTwo">
    <form>
    <fieldset>
    <legend></legend>
    <input type="email" name="username" placeholder="email@address.com" id="username">
    <button type="button">Next</button>
    </fieldset>
    </form>
    </template>

    <form-one api="/accounts"></form-one>
    <form-two api="/accounts"></form-two>

    笔记:
    在上面的代码中 <TEMPLATE>.content移动 到 shadowDOM。
    重复使用(克隆) <TEMPLATE>代码必须是: super(document.getElementById("FormTwo").content.cloneNode(true));为什么你的 template.content失败的
    您的代码失败,因为
      const template = document.createElement('template');
    const form = document.createElement("form");
    template.appendChild(form);
    template没有内容 TEMPLATE不是常规的 HTMLElement, 您必须附加到 .content
      const template = document.createElement('template');
    const form = document.createElement("form");
    template.content.appendChild(form);
    将工作
    大多数 Web 组件示例显示:
      const template = document.createElement("template");
    template.innerHTML = "Hello World"
    innerHTML.content在引擎盖下
    这解释了为什么而不是: template.content.appendChild(form);你可以写: template.innerHTML = form.outerHTML;

    关于javascript - 如何将 TEMPLATE 元素附加到 shadow dom?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63256565/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com