如何使用自定义元素将子自定义元素包装成 div
How to use a custom element to wrap child custom elements into a div
我正在尝试创建一个包装器自定义元素,将其子自定义元素包装到 div。
但是子元素没有换行。相反,一个空的 div 被插入到子元素
之前的包装元素中
<script>
class ListItem extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.innerHTML = "<div>ListItem</div>";
}
}
class List extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.innerHTML = `<div class="list">${this.innerHTML}</div>`;
}
}
customElements.define("list-item", ListItem);
customElements.define("my-list", List);
</script>
<my-list>
<list-item></list-item>
<list-item></list-item>
<list-item></list-item>
</my-list>
这是结果:
<my-list>
<div class="list"></div>
<list-item><div>ListItem</div></list-item>
<list-item><div>ListItem</div></list-item>
<list-item><div>ListItem</div></list-item>
</my-list>
我预计会出现以下情况:
<my-list>
<div class="list">
<list-item><div>ListItem</div></list-item>
<list-item><div>ListItem</div></list-item>
<list-item><div>ListItem</div></list-item>
</div>
</my-list>
你可以试试here。
这是解析执行顺序的问题。当检测到 <my-list>
标签时,会在插入 children 之前立即创建(并连接)它。
作为结果 ${this.innerHTML}
将 return 为 connectedCallback()
中的空字符串。
您可以等待 children 被解析,例如在 setTimeout()
:
的帮助下
class List extends HTMLElement {
connectedCallback() {
setTimeout( () =>
this.innerHTML = `<div class="list">${this.innerHTML}</div>`
)
}
}
但是你最好使用阴影 DOM 和 <slot>
来插入光的元素 DOM:
class List extends HTMLElement {
connectedCallback() {
this.attachShadow( { mode: 'open' } )
.innerHTML = `<div class="list"><slot></slot></div>`
}
}
参见下面的示例。
class ListItem extends HTMLElement {
connectedCallback() {
this.innerHTML = "<div>ListItem</div>";
}
}
class List extends HTMLElement {
connectedCallback() {
this.attachShadow( { mode: 'open' } )
.innerHTML = `<div class="list"><slot></slot></div>`
}
}
customElements.define("list-item", ListItem);
customElements.define("my-list", List);
<my-list>
<list-item></list-item>
<list-item></list-item>
<list-item></list-item>
</my-list>
我正在尝试创建一个包装器自定义元素,将其子自定义元素包装到 div。
但是子元素没有换行。相反,一个空的 div 被插入到子元素
之前的包装元素中<script>
class ListItem extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.innerHTML = "<div>ListItem</div>";
}
}
class List extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.innerHTML = `<div class="list">${this.innerHTML}</div>`;
}
}
customElements.define("list-item", ListItem);
customElements.define("my-list", List);
</script>
<my-list>
<list-item></list-item>
<list-item></list-item>
<list-item></list-item>
</my-list>
这是结果:
<my-list>
<div class="list"></div>
<list-item><div>ListItem</div></list-item>
<list-item><div>ListItem</div></list-item>
<list-item><div>ListItem</div></list-item>
</my-list>
我预计会出现以下情况:
<my-list>
<div class="list">
<list-item><div>ListItem</div></list-item>
<list-item><div>ListItem</div></list-item>
<list-item><div>ListItem</div></list-item>
</div>
</my-list>
你可以试试here。
这是解析执行顺序的问题。当检测到 <my-list>
标签时,会在插入 children 之前立即创建(并连接)它。
作为结果 ${this.innerHTML}
将 return 为 connectedCallback()
中的空字符串。
您可以等待 children 被解析,例如在 setTimeout()
:
class List extends HTMLElement {
connectedCallback() {
setTimeout( () =>
this.innerHTML = `<div class="list">${this.innerHTML}</div>`
)
}
}
但是你最好使用阴影 DOM 和 <slot>
来插入光的元素 DOM:
class List extends HTMLElement {
connectedCallback() {
this.attachShadow( { mode: 'open' } )
.innerHTML = `<div class="list"><slot></slot></div>`
}
}
参见下面的示例。
class ListItem extends HTMLElement {
connectedCallback() {
this.innerHTML = "<div>ListItem</div>";
}
}
class List extends HTMLElement {
connectedCallback() {
this.attachShadow( { mode: 'open' } )
.innerHTML = `<div class="list"><slot></slot></div>`
}
}
customElements.define("list-item", ListItem);
customElements.define("my-list", List);
<my-list>
<list-item></list-item>
<list-item></list-item>
<list-item></list-item>
</my-list>