如何访问 Web 组件中的未命名的插槽内容

问题描述

如何使用 javascript 访问 web 组件的 connectedCallback 中未命名插槽的内容(在本例中为='我需要访问此文本节点')?

使用 javascript shadowRoot 只显示里面没有任何内容。但是 Chrome 会按预期正确呈现它。

谢谢

请注意,为简洁起见,问题中省略了实际的类构造函数

 <template id="my-option-template">
         <slot></slot>
  </template>

.......

使用上面的模板

<my-option>I need to access this text node</my-option> 

解决方法

您需要注意一两种技术行为:

  • 开槽内容反射lightDOMshadowDOM <slot>
    未移动
    因此,您可以在 容器 CSS 中设置 lightDOM 内容的样式(以下示例为“绿色”颜色中的全局 CSS)
    长答案见:::slotted CSS selector for nested children in shadowDOM slot

  • connectedCallbackopening 标签 <my-element>
    上触发 它的其余(innerHTML)内容尚未解析。
    库会帮助处理更多稍后触发的回调..
    但是为什么要加载 2 kB,并添加依赖项,
    当您可以使用 setTimeout

    自己编写相同的延迟时

<template id="MY-ELEMENT">
   <h3>Slotted content:</h3>
   <slot></slot>
   <h3>Appended content:</h3>
   <h2></h2>
</template>

<style>
   my-element    { color:red }
   my-element h2 { color:green }
</style>

<my-element>
   <h2>need to access this text node</h2>
</my-element>

<script>
   customElements.define('my-element',class extends HTMLElement {
     constructor() {
       let template = (id) => document.getElementById(id).content.cloneNode(true);
       super() // sets and returns this scope
         .attachShadow({ mode: "open" }) // sets and returns this.shadowRoot
         .append(template(this.nodeName));
     }
     connectedCallback() {
       setTimeout(() => {
         this.shadowRoot.querySelector("H2").append(this.innerHTML)
       })
     }
   });
 </script>

,

可以在 this.shadowRoot.querySelectorAll('slot') 中使用 connectedCallback,这将为您提供所有定义插槽的 NodeList。可以使用 assignedNodes 方法访问插槽的内容。然后,您可以选择将 slotchange 事件侦听器应用于要在插槽内容更改时通知的插槽元素:

<my-option><b>I need to access this text node</b></my-option>


<script>
customElements.define('my-option',class extends HTMLElement {

    constructor() {

        super(); // sets and returns this scope

        var shadow = this.attachShadow({mode: 'open'});

        shadow.innerHTML ='<slot></slot>';
    }


    connectedCallback() {
        let slots = this.shadowRoot.querySelectorAll('slot');
        console.log(slots);

        slots[0].addEventListener('slotchange',function(e) {
            let nodes = slots[0].assignedNodes();
            console.log(nodes);
        });
    }
});
</script>

关于https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement的更多信息