我试图制作一个经典的菜单栏,并同时使用Web组件。我从没和他们玩过,这是我第一次涉足这个领域。它们似乎是一个非常强大的工具,但是关于我正在尝试做的事情似乎没有太多可用信息。
我有一棵自定义html元素的树,当前看起来像这样(在调用构造函数之后):
<menu-bar>
<sub-menu label="some label">
<label>some label</label>
<menu-item></menu-item>
<menu-item></menu-item>
<menu-item></menu-item>
</sub-menu>
</menu-bar>
如何使自定义元素将其变成...
<menu-bar>
<sub-menu label="some label">
<label>some label</label>
<div>
<menu-item></menu-item>
<menu-item></menu-item>
<menu-item></menu-item>
</div>
</sub-menu>
</menu-bar>
...何时调用子菜单的构造函数?还有可能使div成为影子dom的一部分,而菜单项元素不在影子dom中吗?
相关示例代码
class MenuBar extends HTMLElement {
constructor() {
super();
}
};
class SubMenu extends HTMLElement {
constructor() {
super();
let shadowRoot = this.attachShadow({mode: "open"});
this.labelElement = document.createElement("label");
shadowRoot.appendChild(this.labelElement);
}
static get observedAttributes() {
return ["label"];
}
attributeChangedCallback(pName, pOldValue, pNewValue) {
switch (pName) {
case "label":
this.labelElement.innerHTML = pNewValue;
break;
}
}
};
class MenuItem extends HTMLElement {
constructor() {
super();
}
};
window.customElements.define("menu-bar", MenuBar);
window.customElements.define("sub-menu", SubMenu);
window.customElements.define("menu-item", MenuItem);
任何帮助都将不胜感激,因为我正在学习这些功能的工作原理,并且正在寻找更多有关使用Web组件操作预定义html的细节的信息,而不只是直接回答此确切示例本身。
答案 0 :(得分:2)
您需要使用<slot>
来允许非shadowDOM子级显示在元素的shadowDOM中。
示例:
class MenuBar extends HTMLElement {
constructor() {
super();
}
};
class SubMenu extends HTMLElement {
constructor() {
super();
let shadowRoot = this.attachShadow({mode: "open"});
this.labelElement = document.createElement("label");
let temp = document.createElement("div");
temp.innerHTML = '<slot></slot>';
shadowRoot.appendChild(this.labelElement);
shadowRoot.appendChild(temp);
}
static get observedAttributes() {
return ["label"];
}
attributeChangedCallback(pName, pOldValue, pNewValue) {
switch (pName) {
case "label":
this.labelElement.innerHTML = pNewValue;
break;
}
}
};
class MenuItem extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: "open"}).innerHTML = `
<style>
:host {
background-color: #eee;
border: 1px solid #ddd;
display:block;
margin: 1px 0;
}
</style>
<slot></slot>
`;
}
};
window.customElements.define("menu-bar", MenuBar);
window.customElements.define("sub-menu", SubMenu);
window.customElements.define("menu-item", MenuItem);
<menu-bar>
<sub-menu label="some label">
<menu-item>1</menu-item>
<menu-item>2</menu-item>
<menu-item>3</menu-item>
</sub-menu>
</menu-bar>
在您的SubMenu
中,我在<div>
上添加了<slot>
,以容纳所有<menu-item>
组件。
我还添加了一些次要CSS,以便于查看子元素。