Внедрить содержимое из <template>в <slot> - PullRequest
0 голосов
/ 24 февраля 2019

Я хочу получить содержимое шаблона, внедрить его в пользовательский элемент с теневым DOM и применить стили к span внутри template с помощью селектора ::slotted, но, похоже, это работает не так, как ожидалось.

<!doctype html>
<html lang="en">
    <head>
        <template id="template">
            <span>element from template</span>
        </template>
    </head>
    <body>
        <script type="text/javascript">
            class WithShadowDom extends HTMLElement {
                constructor() {
                    super();
                    const shadowRoot = this.attachShadow({mode: 'open'});
                    shadowRoot.innerHTML = `
                        <style>
                            ::slotted(span) {
                                font-size: 25px;
                            }
                        </style>
                    `;
                    shadowRoot
                        .appendChild(document.createElement('slot'))
                        .appendChild(
                            document.getElementById('template').content.cloneNode(true)
                        );
                }
            }
            window.customElements.define('with-shadow-dom', WithShadowDom);
            const myCustomElement = document.createElement('with-shadow-dom');
            document.body.appendChild(myCustomElement);
        </script>
    </body>
</html>

Следующая часть не работает должным образом.font-size css не применяется.

shadowRoot
    .appendChild(document.createElement('slot'))
    .appendChild(document.getElementById('template').content.cloneNode(true));

В то время как при прямом добавлении дочернего элемента span в пользовательский элемент применяется font-size.

const span = document.createElement('span');
span.innerHTML = 'asdffad';
shadowRoot
    .appendChild(document.createElement('slot'))
    .appendChild(span);

1 Ответ

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

Вы добавили промежуток к теневому дому.Вместо этого вы должны добавить его в light dom, если хотите, чтобы он был вставлен в <slot> месте.

connectedCallback() {
    //template content
    this.appendChild(document.getElementById('template').content.cloneNode(true));
    //span element
    const span = document.createElement('span');
    span.innerHTML = 'asdffad';
    this.appendChild(span);
}

Примечание: вы не должны добавлять некоторый контент в light DOM в constructor().Вместо этого сделайте это в методе connectedCallback().

Когда вы посмотрите на панель Elements в консоли разработчика, вы увидите, что при добавлении фрагмента или элемента HTML результат будет другим.<slot> и DOM света.

...