如果我手动将一个template
节点写入HTML,则可以在我的自定义元素中使用它。如果我创建一个template
节点并在尝试使用它时使用javascript将其附加到HTML,则它为空...
在下面的示例中,我将template-a
设置为常规HTML方式,并使用javascript将template-b
设置为相同形状。我定义了一个使用两个模板的非常简单的自定义元素。只有template-a
是可见的。
const sandbox = document.getElementById('sandbox')
const slot = document.createElement('slot')
slot.setAttribute('name', 'b')
slot.append('slot content goes here')
const em = document.createElement('em')
em.append(slot, '?')
const createdTemplate = document.createElement('template')
createdTemplate.setAttribute('id', 'template-b')
createdTemplate.append(em)
sandbox.append(createdTemplate)
customElements.define('test-element', class extends HTMLElement {
constructor () {
super()
this.attachShadow({ mode: 'open' }).append(
...['template-a','template-b']
.map(id =>
document.getElementById(id).content.cloneNode(true)
)
)
}
})
<div id="sandbox">
<template id="template-a">
<strong><slot name="a">slot content goes here</slot>!</strong>
</template>
<test-element>
<span slot="a">some a slot content</span>
<span slot="b">some b slot content</span>
</test-element>
</div>
答案 0 :(得分:1)
关于代码的一些注释:
this.shadow = this.attachShadow({ mode: 'open' })
可以成为
this.attachShadow({ mode: 'open' })
这免费创建/设置了this.shadowRoot
请注意,.appendChild(el)
包含一个元素
和.append()
带一个数组
唯一的区别是appendChild()
返回对插入元素的引用,
并且append()
不返回任何内容
所以您可以写:
em.appendChild(slot)
em.appendChild(document.createTextNode('?'))
为
em.append(slot, document.createTextNode('?'))
如果阵列中有节点:
let myElements = [slot, document.createTextNode('?')];
您可以使用ES6扩展运算符:
em.append(...myElements)
这意味着您可以编写:
this.shadow.appendChild(document.getElementById('template-a').content.cloneNode(true))
this.shadow.appendChild(document.getElementById('template-b').content.cloneNode(true))
为:
this.shadowRoot
.append(
...['a','b']
.map(templ => document.getElementById(`template-${templ}`).content.cloneNode(true))
)
答案 1 :(得分:0)
template
节点具有一个特殊的content
属性,该属性保存其子级。 (我有点知道,但认为它比它更具魔力)。如果这行:
createdTemplate.append(em)
更改为
createdTemplate.content.append(em)
然后一切正常
const sandbox = document.getElementById('sandbox')
const slot = document.createElement('slot')
slot.setAttribute('name', 'b')
slot.append('slot content goes here')
const em = document.createElement('em')
em.append(slot, '?')
const createdTemplate = document.createElement('template')
createdTemplate.setAttribute('id', 'template-b')
createdTemplate.content.append(em)
sandbox.append(createdTemplate)
customElements.define('test-element', class extends HTMLElement {
constructor () {
super()
this.attachShadow({ mode: 'open' }).append(
...['template-a','template-b']
.map(id =>
document.getElementById(id).content.cloneNode(true)
)
)
}
})
<div id="sandbox">
<template id="template-a">
<strong><slot name="a">slot content goes here</slot>!</strong>
</template>
<test-element>
<span slot="a">some a slot content</span>
<span slot="b">some b slot content</span>
</test-element>
</div>