【问题标题】:Inject content from <template> into <slot>将 <template> 中的内容注入 <slot>
【发布时间】:2019-07-18 01:58:51
【问题描述】:

我想获取模板内容,将其注入到带有阴影 DOM 的自定义元素中,并通过 ::slotted 选择器将样式应用于 template 内的 span,但这似乎无法按预期工作。

<!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);

【问题讨论】:

    标签: javascript web-component shadow-dom custom-element html-templates


    【解决方案1】:

    您已将跨度附加到影子 dom。如果您希望将其插入 &lt;slot&gt; 位置,则应将其添加到 light dom。

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

    注意:您不应将某些内容附加到 constructor() 中的 light DOM。而是在 connectedCallback() 方法中执行此操作。

    当您查看开发者控制台中的 Elements 窗格时,您会发现当您将 HTML 片段或元素添加到 &lt;slot&gt; 和 light DOM 时,结果会有所不同。 p>

    【讨论】:

    • 但我将span 附加为slot 的子代,而不是直接作为shadowRoot 的子代,因此它实际上是添加到轻DOM 中的。此外,我并不是在抱怨span 的行为,它按我的预期工作,我的问题是关于templatetemplate 中的 span 元素不采用 ::slotted(span) 中定义的样式
    • @YuriyKravets 不,你不能通过 元素向轻量级 DOM 添加一些东西(模板内容或跨度)。它行不通。您应该直接将其添加到 light dom 中。
    猜你喜欢
    • 2021-10-13
    • 1970-01-01
    • 2022-12-28
    • 2017-10-13
    • 1970-01-01
    • 2021-03-27
    • 1970-01-01
    • 2017-06-10
    • 2021-02-06
    相关资源
    最近更新 更多