【问题标题】:Why does cloneNode need to be used when using <template/> with Shadow Dom为什么在使用<template/>和Shadow Dom时需要使用cloneNode
【发布时间】:2021-05-08 08:52:56
【问题描述】:

我一直在查看有关 Web 组件的 mdn 文档,我点击了链接,然后我到达了有关模板的文档,链接下方就是我正在查找的内容。

根据文件

它说如果我不使用 cloneNode 附加节点?模板的内部样式将不起作用。但是我尝试使用 cloneNode 进行追加和追加,但两个测试都是相同的......所以我有一个问题是我想念理解或规范更改以支持两者?我在 chrome 和 safari 中测试这两个浏览器

没有 cloneNode 的代码

<template id="my-paragraph">
    <style>
      p {
        color: white;
        background-color: #666;
        padding: 5px;
      }
    </style>
    <p>My paragraph</p>
  </template>
<my-paragraph></my-paragraph>

<script>
  customElements.define('my-paragraph',
    class extends HTMLElement {
      constructor() {
        super();
        let template = document.getElementById('my-paragraph');
        let templateContent = template.content;
        const shadowRoot = this.attachShadow({
          mode: 'open'
        })
        var style = document.createElement('style');
        style.textContent = `
p{
  font-size: 30px;
  color:'black';
}`;
        shadowRoot.appendChild(style)
        console.log(template)
        shadowRoot.appendChild(templateContent);
      }
    }
  );
</script>

使用 cloneNode 的代码

<template id="my-paragraph">
    <style>
      p {
        color: white;
        background-color: #666;
        padding: 5px;
      }
    </style>
    <p>My paragraph</p>
  </template>
<my-paragraph></my-paragraph>

<script>
  customElements.define('my-paragraph',
    class extends HTMLElement {
      constructor() {
        super();
        let template = document.getElementById('my-paragraph');
        let templateContent = template.content;
        const shadowRoot = this.attachShadow({
          mode: 'open'
        })
        var style = document.createElement('style');
        style.textContent = `
p{
  font-size: 30px;
  color:'black';
}`;
        shadowRoot.appendChild(style)
        console.log(template)
        shadowRoot.appendChild(templateContent.cloneNode(true));
      }
    }
  );
</script>

https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_templates_and_slots

【问题讨论】:

    标签: web-component shadow-dom clonenode html-templates


    【解决方案1】:

    .content 移动内容,
    .content.cloneNode(true)制作&lt;template&gt;深拷贝

    参见下面的 SO sn-p; 3rd &lt;my-paragraph&gt; 无法从 &lt;template&gt; 获取任何内容,因为 2nd &lt;my-paragraph&gt; 已将所有模板移动到其&lt;my-paragraph&gt; shadowDOM

    <template id="MY-PARAGRAPH">
        <style>
          p {
            background: lightgreen;
            padding: 5px;
          }
        </style>
        <p><slot></slot></p>
      </template>
    <my-paragraph cloned>Cloned Content</my-paragraph>
    <my-paragraph>Content only</my-paragraph>
    <my-paragraph>Content only</my-paragraph>
    <script>
      customElements.define('my-paragraph',
        class extends HTMLElement {
          constructor() {
            // yes you can place javascript BEFORE the super() call, the docs are wrong
            const template = () => {
              let content = document.getElementById(this.nodeName).content;
              if (content.children.length) {
                if (this.hasAttribute("cloned"))
                  return content.cloneNode(true)
                else
                  return content;
              } else {
                document.body.append(`content in template: `, this.nodeName);
              }
            }
            super() // sets AND returns this-Scope
              .attachShadow({mode: 'open'})  // sets AND returns this.shadowRoot
              .append(template()) // no need for appendChild if you don't use its return value
          }
        }
      );
    </script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-16
      • 1970-01-01
      • 2018-02-05
      • 1970-01-01
      • 2021-07-14
      • 1970-01-01
      • 2015-03-21
      相关资源
      最近更新 更多