如何访问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> 

可以在connectedCallback中使用this.shadowRoot.querySelectorAll('slot'),这将为您提供所有已定义插槽的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

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

  • 开槽内容被lightDOM反射shadowDOM<slot>
    它是未移动
    因此,您可以在容器CSS中设置lightDOM内容的样式(下面的"绿色"示例中的全局CSS(
    有关详细答案,请参阅::shadowDOM插槽中嵌套子项的槽式CSS选择器

  • 打开标记<my-element>
    connectedCallback触发器其其余(innerHTML(内容尚未解析
    库帮助处理稍后启动的更多回调
    但是为什么要加载2kB并添加依赖项,
    当您可以使用setTimeout自己编写一个微小的延迟时(只要您的lightDOM内容不是很大就可以工作(

  • 另请参阅此答案:web组件中嵌套插槽的内容不可见

<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>

  • 请注意my-element h2{ color:green }是如何而不是在shadowDOM
    内对<h2>进行样式设置的,因为一些样式属性级联到shadowDOMttps://lamplightdev.com/blog/2019/03/26/why-is-my-web-component-inheriting-styles/

  • 所有带有requestAnimationFrame、Promises等的库"延迟"回调实现实际上都是一样的:等待事件循环为空

    事件循环到底是什么
    Philip Roberts:https://www.youtube.com/watch?v=8aGhZQkoFbQ

最新更新