如何解决shadow dom 内的重复命名插槽不起作用
我有一个看起来像这样的自定义元素:
class RepeatMe extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
let slot = document.createElement('slot');
slot.setAttribute('name','bar');
this.shadowRoot.append(slot);
slot = document.createElement('slot');
slot.setAttribute('name','content');
this.shadowRoot.append(slot);
slot = document.createElement('slot');
slot.setAttribute('name','bar');
this.shadowRoot.append(slot);
}
}
window.customElements.define('repeat-me',RepeatMe);
我使用它如下:
<repeat-me>
<div slot="bar">I'm a bar</div>
<div slot="content">I'm some content</div>
</repeat-me>
我想在 shadow dom 中重复插槽 bar
(因为开头和结尾的内容相同),但我得到的是只有第一个插槽被渲染并且第二个是空的。我正在尝试使用 shadow dom 插槽做些什么,或者您知道某种方法可以实现这样的目标吗?
解决方法
不,插槽是独一无二的,
并且多个 lightDOM 元素可以插入到同一个 SLOT
将 SLOT 视为您的邮箱;您是否希望您的邮件总是复制到另一个邮箱?
如果你有这个要求,你需要一个过滤器来复制电子邮件(或插槽内容)
WebComponents 有 2 个复制选项:
-
将
<span slot="bar">
克隆到 shadowRoot 中的其他(非插槽)DOM 元素 -
克隆到新的 lightDOM 元素
<span slot="duplicate_bar1">
用于新插入的内容
下面的代码为 slotchange
上发生的 <span slot="bar">
事件提供了两个选项(槽中的新内容)
-
在
slotchange
上,插槽内容被克隆到class="duplicate_bar"
(let dups = ...
) -
在
slotchange
上创建新的 lightDOM 元素 (let dupslots = ...
)
请注意,只有方法 2. 使用 <slot>
功能,您可以使用 :slotted
样式
此代码仅复制内容;它不会清理已删除的 SLOT 内容。
<my-element>
<span slot="bar"> ONE </span>
<span slot="bar"> TWO </span>
<span slot="content"> content </span>
</my-element>
<template id="MY-ELEMENT">
<style>
::slotted(*) { background: lightgreen }
</style>
slot bar: <slot name="bar"></slot>
<br> slot: content: <slot name="content"></slot>
<br>Duplicate in SPAN: <span class="duplicate_bar"></span>
<br>Duplicate in B:<b class="duplicate_bar"></b>
<br>duplicate_bar1:<slot name="duplicate_bar1"></slot>
<br>duplicate_bar2:<slot name="duplicate_bar2"></slot>
</template>
<script>
customElements.define('my-element',class extends HTMLElement {
constructor() {
let template = id => document.getElementById(id).content.cloneNode(true);
super().attachShadow({mode: 'open'}).append(template(this.nodeName));
let slotname = "bar";
let slot = this.shadowRoot.querySelector(`[name="${slotname}"]`);
slot.addEventListener("slotchange",(evt) => {
let assigned = slot.assignedNodes();
let dups = [...this.shadowRoot.querySelectorAll(".duplicate_" + slotname)];
let dupslots = [...this.shadowRoot.querySelectorAll(`slot[name*="duplicate_bar"]`)];
assigned.forEach(node => {
dups.forEach(el => el.append(node.cloneNode(true)));
dupslots.forEach(duplicateslot => {
let newNode = node.cloneNode(true);
newNode.slot = duplicateslot.name; // set BEFORE adding to DOM! otherwise 'bar' slotchange Events triggers on it
this.append(newNode);
})
});
});
}
});
</script>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。