[英]How to use HTML node as slot?
我对web-components
完全陌生,无法弄清楚哪个部分出了问题。
我正在尝试创建一个包含button
的web-component
,该按钮应该显示和隐藏p
标签。 下面是代码,它工作正常。
class SpecialButton extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this._toShow = false;
this.shadowRoot.innerHTML = `
<style>
p {
display: none;
}
</style>
<button>Show</button>
<slot><p>default paragraph!</p></slot>
`;
}
connectedCallback() {
const button = this.shadowRoot.querySelector('button');
const p = this.shadowRoot.querySelector('p');
if (this.hasAttribute('toShow')) {
this._toShow = this.getAttribute('toShow');
if (this._toShow) {
button.textContent = 'Hide';
p.style.display = 'block';
this._toShow = false;
} else {
button.textContent = 'Show';
p.style.display = 'none';
this._toShow = true;
}
}
button.addEventListener('click', () => {
if (this._toShow) {
button.textContent = 'Hide';
p.style.display = 'block';
this._toShow = false;
} else {
button.textContent = 'Show';
p.style.display = 'none';
this._toShow = true;
}
});
}
}
customElements.define('uc-button', SpecialButton);
如果我不将任何东西传递给uc-button
,它会很好用
<uc-button toShow="true"></uc-button>
我现在面临的问题是我试图从我的html
传递一个p
作为slot
<uc-button toShow="true"><p>GGGGGGG</p></uc-button>
结果, <p>GGGGGGG</p>
似乎总是显示,我不确定是哪一部分出了问题。 我是不是理解错了slot
,只能接受string不能接受HTML Node?
更新我创建了一个可重现的演示 @ https://codesandbox.io/s/inspiring-hill-evgol?file=/index.html
在connectedCallback
方法中,您将从 shadowRoot 获取“button”和“p”元素。 这些是默认的。 使用组件时传递的那个不在 shadowRoot 中
<uc-button toShow="true"><p>GGGGGGG</p></uc-button>
connectedCallback() {
const p = this.shadowRoot.querySelector("p");
// this "p" isn't the one passed with the "GGGGGGG" textContent, but the one with "Default Paragraph"
}
您传递的元素在light DOM中因此您可以查询 light dom:
const p = this.querySelector("p");
然而,在connectedCallback
运行时,light DOM 中的元素还没有被“移动”(它们并没有真正移动,只是呈现在自定义元素<slot>
所在的位置。因此,它们被称为分布式节点) . 所以此时你不能查询它们。
那么,什么时候才能拿到那些分布式节点呢? 浏览器会告诉你在 shadowRoot onslotchange上触发的事件
您可以监听插槽中的变化,然后应用监听器。
connectedCallback() {
// Notice that we bind the callback to "this" because otherwise it'll be shadowRoot,
// and with the code below you would be still querying the shadowRoot.
this.shadowRoot.addEventListener('slotchange', this.onSlotChange.bind(this));
}
onSlotChange() {
const p = this.querySelector("p");
// this is the passed "p"
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.