我有一个定义的Web组件自定义元素。
<template id="dropdown-template">
<select>
<slot></slot>
</select>
</template>
<script>
class Dropdown extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
let template = document.getElementById('dropdown-template');
shadowRoot.appendChild(template.content.cloneNode(true));
}
}
customElements.define("drop-down", Dropdown);
</script>
尝试使用它时,我尝试将带有值的选项标签传递到自定义元素中。
<drop-down>
<option>one</option>
<option>two</option>
<option>three</option>
</drop-down>
这不起作用。选择元素显示有一个<slot>
元素作为其直接子元素,并且不呈现选项。这与<select>
标签不符吗?
答案 0 :(得分:0)
不可能那样做,因为<option>
标签的父元素必须是<select>
标签。因此,您可以使用Shadow DOM,因为<slot>
元素会破坏父级/子级层次结构。
解决方案1:移动元素
一种解决方法是将轻型DOM的内容移动到模板中<select>
元素内。
class Dropdown extends HTMLElement {
constructor() {
super()
const shadowRoot = this.attachShadow( {mode: 'open'} )
let template = document.getElementById( 'dropdown-template' )
shadowRoot.appendChild( template.content.cloneNode(true) )
const select = shadowRoot.querySelector( 'select' )
shadowRoot.addEventListener( 'slotchange', ev => {
let node = this.querySelector( 'option' )
node && select.append( node )
} )
}
}
customElements.define("drop-down", Dropdown);
<template id="dropdown-template">
<select></select>
<slot></slot>
</template>
<drop-down>
<option>one</option>
<option>two</option>
<option>three</option>
</drop-down>
解决方案2:自定义<select>
另一种可能性是避免使用Shadow DOM,并将下拉列表定义为自定义的内置<select>
元素。如果您想自定义布局,这可能不符合您的需求。
<select is="drop-down">
<option>one</option>
<option>two</option>
<option>tree</option>
</select>