是否有一种方法可以将每个单独的元素分隔到特定槽名的阴影区域中?
假设标记看起来类似于
<custom-element>
<div name="item">item 1</div>
<div name="item">item 2</div>
</custom-element>目前,呈现类似于:
<custom-element>
<div class="wrap">
<div name="item">item 1</div>
<div name="item">item 2</div>
</div>
</custom-element>我将如何包装有槽的元素以输出,类似于:
<custom-element>
<div class="wrap">
<div name="item">item 1</div>
</div>
<div class="wrap">
<div name="item">item 2</div>
</div>
</custom-element>我目前(有缺陷的)方法:
customElements.define('custom-element', class MyCustomElement extends HTMLElement {
constructor(...args) {
super(...args);
let shadow = this.attachShadow({mode: open});
shadow.innerHTML = `
<div class="wrap">
<slot name="item"></slot>
</div>
`;
}
});发布于 2020-02-26 15:23:16
我建议你改变你对孩子们包装的态度。最简单的方法是将缺失的HTML添加为开槽div的子程序,如下例所示。您仍然可以使用::slotted伪选择器对时隙元素进行样式设置。
customElements.define('custom-element', class MyCustomElement extends HTMLElement {
constructor(...args) {
super(...args);
let shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>
::slotted([slot="item"]) {
border: 1px solid black;
padding: 15px;
}
</style>
<slot name="item"></slot>
`;
}
});<custom-element>
<div slot="item">
<div class="wrap">item 1</div>
</div>
<div slot="item">
<div class="wrap">item 2</div>
</div>
</custom-element>
这种方法背后的原因是,包装最终属于子元素,并且应该与每个子元素一起使用。结果将与您所要求的类似。
尽管,如果您确实想动态地向元素添加包装,那么您可以处理slotchange事件。只要填充了一个插槽,并且可以从ShadowRoot元素中听到该事件,就会触发该事件。在事件中,assignedElements上的回调循环(它们是槽中的元素)并更改它们的innerHTML值。
customElements.define('custom-element', class MyCustomElement extends HTMLElement {
constructor(...args) {
super(...args);
let shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `<slot name="item"></slot>`;
shadow.addEventListener('slotchange', event => {
const { target } = event;
const assignedElements = target.assignedElements();
for (const element of assignedElements) {
if (element.querySelector('.wrap') === null) {
const wrapper = document.createElement('div');
wrapper.className = 'wrap';
for (const node of element.childNodes) {
wrapper.appendChild(node);
}
element.append(wrapper);
}
}
});
}
});.wrap {
border: 1px solid black;
padding: 15px;
}<custom-element>
<div slot="item">item 1</div>
<div slot="item">
<div class="wrap">item 2</div>
</div>
</custom-element>
发布于 2022-07-17 22:14:10
我也面临过同样的问题,这就是我想出的解决方案:重新定位项目插槽。我有一个“主”槽,它应该始终是空的--在每个slotchange事件上,我迭代新项,为每个条目创建一个新的包装器,并在每个包装器中创建一个动态生成的名称。然后,我将更改原始项的“槽”属性,将其移动到该时隙。
customElements.define('buttons', class extends HTMLElement {
__allocateId()
{
var i = 0;
while ( this.__buttons.has( "btn" + i ) ) {
++i;
}
return "btn" + i;
}
__onButtonSlotChange(button)
{
if (button.contentSlot.assignedNodes({flatten: true}).length == 0) {
this.__buttons.delete(button.id);
button.remove();
}
}
__onMainSlotChange() {
for (var element of this.mainSlot.assignedElements({flatten: true})) {
var button = document.createElement('arrow-button');
button.id = this.__allocateId();
this.shadowRoot.appendChild(button);
var subSlot = document.createElement('slot');
subSlot.name = button.id;
button.appendChild(subSlot);
button.contentSlot = subSlot;
subSlot.addEventListener('slotchange', this.__onButtonSlotChange.bind(this, button));
element.setAttribute("slot", button.id);
this.__buttons.set(button.id, button);
}
}
constructor() {
super();
this.__buttons = new Map();
}
connectedCallback() {
var shadowRoot = this.attachShadow({mode: 'open'});
this.mainSlot = document.createElement('slot');
shadowRoot.appendChild(this.mainSlot);
var buttonList = document.createElement('div');
shadowRoot.appendChild(buttonList);
this.mainSlot.addEventListener('slotchange', this.__onMainSlotChange.bind(this));
}
});这对原始对象的影响最小,在对“按钮”代码进行任何修改时,整个组件的行为都是正确的-例如。项删除触发相应按钮的删除。
https://stackoverflow.com/questions/60393993
复制相似问题