如何使用自定义元素将子自定义元素包装成 div

How to use a custom element to wrap child custom elements into a div

我正在尝试创建一个包装器自定义元素,将其子自定义元素包装到 div。

但是子元素没有换行。相反,一个空的 div 被插入到子元素

之前的包装元素中
<script>
  class ListItem extends HTMLElement {
    constructor() {
      super();
    }

    connectedCallback() {
      this.innerHTML = "<div>ListItem</div>";
    }
  }

  class List extends HTMLElement {
    constructor() {
      super();
    }

    connectedCallback() {
      this.innerHTML = `<div class="list">${this.innerHTML}</div>`;
    }
  }

  customElements.define("list-item", ListItem);
  customElements.define("my-list", List);
</script>

<my-list>
  <list-item></list-item>
  <list-item></list-item>
  <list-item></list-item>
</my-list>

这是结果:

<my-list>
  <div class="list"></div>
  <list-item><div>ListItem</div></list-item>
  <list-item><div>ListItem</div></list-item>
  <list-item><div>ListItem</div></list-item>
</my-list>

我预计会出现以下情况:

<my-list>
  <div class="list">
    <list-item><div>ListItem</div></list-item>
    <list-item><div>ListItem</div></list-item>
    <list-item><div>ListItem</div></list-item>
  </div>
</my-list>

你可以试试here

这是解析执行顺序的问题。当检测到 <my-list> 标签时,会在插入 children 之前立即创建(并连接)它。

作为结果 ${this.innerHTML} 将 return 为 connectedCallback() 中的空字符串。

您可以等待 children 被解析,例如在 setTimeout():

的帮助下
class List extends HTMLElement {
    connectedCallback() {
        setTimeout( () => 
            this.innerHTML = `<div class="list">${this.innerHTML}</div>` 
        )
    }
}

但是你最好使用阴影 DOM 和 <slot> 来插入光的元素 DOM:

class List extends HTMLElement {
    connectedCallback() {
        this.attachShadow( { mode: 'open' } )
            .innerHTML = `<div class="list"><slot></slot></div>` 
    }
}

参见下面的示例。

class ListItem extends HTMLElement {
    connectedCallback() {
        this.innerHTML = "<div>ListItem</div>";
    }
}

class List extends HTMLElement {
    connectedCallback() {
        this.attachShadow( { mode: 'open' } )
            .innerHTML = `<div class="list"><slot></slot></div>` 
    }
}

customElements.define("list-item", ListItem);
customElements.define("my-list", List);
<my-list>
    <list-item></list-item>
    <list-item></list-item>
    <list-item></list-item>
</my-list>