Как использовать пользовательский элемент для переноса дочерних пользовательских элементов в div - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь создать пользовательский элемент-обертку, который оборачивает его дочерние пользовательские элементы в 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>

Вы можете попробовать это здесь .

1 Ответ

0 голосов
/ 25 января 2019

Это связано с последовательностью выполнения анализа.Когда тег <my-list> обнаружен, он создается (и подключается) немедленно, до того, как вставляются его дочерние элементы.

В результате ${this.innerHTML} вернет пустую строку в connectedCallback().

Вы можете подождать, пока дети не будут проанализированы, например, с помощью setTimeout():

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

Но вам лучше использовать Shadow 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...