Тег шаблона, созданный с использованием JS, не отображается при добавлении в тень внутри веб-компонента

Я ожидал, что следующий код создаст элемент, содержащий div с текстом «Hi» в нем.

Элемент отображается в инспекторе, но на экране не отображается текст.

Когда я меняю шаблон с template на div, появляется текст. Что я здесь сделал не так?

class MyComponent extends HTMLElement {
    constructor() {
        super()

        const shadowRoot = this.attachShadow({ mode: 'open' })
        const template = document.createElement('template')
        const div = document.createElement('div')

        div.innerHTML = 'Hi'
        template.appendChild(div)

        shadowRoot.appendChild(template.content)
    }
}
customElements.define('my-component', MyComponent)

person David Alsh    schedule 13.01.2019    source источник


Ответы (2)


<template> - особый элемент.

Добавьте некоторые HTML-элементы через свойство content:

template.content.appendChild(div)

или добавьте HTML-код через его свойство innerHTML:

template.innerHTML = '<div>Hi</div>'
person Supersharp    schedule 13.01.2019
comment
Другим решением было бы использование fragment. - person connexo; 13.01.2019
comment
да. И на самом деле content - это DocumentFragment - person Supersharp; 13.01.2019
comment
Часть 2 вопроса. Почему я не могу обновить ссылку на template.content? stackblitz.com/edit/js-haybrb - person David Alsh; 14.01.2019
comment
@DavidAlsh, извини, я не понимаю твой вопрос. В предоставленной вами ссылке вы используете this.content, который не имеет смысла, потому что this не является шаблоном, а сам настраиваемый элемент - person Supersharp; 14.01.2019
comment
Вы должны написать: this.shadowRoot.appendChild (div) вместо render () - person Supersharp; 14.01.2019

Я согласен с ответом @ Supersharp. Вот альтернативное решение без необходимости <template>.

class MyComponent extends HTMLElement {
    constructor() {
        super()
        const div = document.createElement('div')
        div.innerHTML = 'Hi'
        this.attachShadow({ mode: 'open' }).appendChild(div)
    }
}
customElements.define('my-component', MyComponent)
<my-component></my-component>

Или вы можете сделать это, просто используя innerHTML из shadowRoot:

class MyComponent extends HTMLElement {
    constructor() {
        super()
        this.attachShadow({ mode: 'open' }).innerHTML = "<div>Hi</div>";
    }
}
customElements.define('my-component', MyComponent)
<my-component></my-component>

person Intervalia    schedule 16.01.2019