Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Html 是否可以通过编程方式在web组件中设置元素的插槽?_Html_Web Component_Shadow Dom_Custom Element_Html Templates - Fatal编程技术网

Html 是否可以通过编程方式在web组件中设置元素的插槽?

Html 是否可以通过编程方式在web组件中设置元素的插槽?,html,web-component,shadow-dom,custom-element,html-templates,Html,Web Component,Shadow Dom,Custom Element,Html Templates,是否可以自动或以编程方式为特定类型的嵌套web组件或元素设置插槽,而无需在其上指定slot属性 考虑如下一些结构: 儿童1 儿童2 内容 由于具有如下阴影DOM: 默认子项 预期结果是: 儿童1 儿童2 内容 换句话说,我想强制执行只能在中使用,类似于元素只能在元素中使用。我想把它们放在元素中。必须在每个插槽上指定插槽属性以将它们放置在的特定插槽中,这似乎是多余的。 同时,中的其余内容应自动插入第二个元素 我首先在注册父元素时搜索了一种定义它的方法,尽管目前只支持extendsas选

是否可以自动或以编程方式为特定类型的嵌套web组件或元素设置插槽,而无需在其上指定
slot
属性

考虑如下一些结构:


儿童1
儿童2
内容

由于
具有如下阴影DOM:


默认子项
预期结果是:


儿童1
儿童2
内容

换句话说,我想强制执行
只能在
中使用,类似于
元素只能在
元素中使用。我想把它们放在
元素中。必须在每个插槽上指定
插槽
属性以将它们放置在
的特定插槽中,这似乎是多余的。 同时,
中的其余内容应自动插入第二个
元素

我首先在注册父元素时搜索了一种定义它的方法,尽管目前只支持
extends
as选项

然后我想,也许有一个函数允许手动设置元素的插槽,例如类似于
childElement.slot('child-elements')
,但这似乎不存在

然后,我尝试在父元素的构造函数中以编程方式实现这一点,如下所示:

constructor(){
超级();
this.attachShadow({mode:'open'});
this.shadowRoot.appendChild(template.content.cloneNode(true));
const childElements=this.getElementsByTagName('child-element');
const childElementSlot=this.shadowRoot.querySelector('[name=“child elements”]');
for(设i=0;i

尽管这不会将子元素移动到
,因此所有子元素仍然会在第二个
元素中开槽。

您的未命名的默认
将捕获未分配给命名的槽的所有元素
因此
slotchange
事件可以捕获这些元素,并强制
子元素
进入正确的插槽:

customElements.define('parent-element',类扩展了HtmleElement{
构造函数(){
super().attachShadow({mode:'open'})
.append(document.getElementById(this.nodeName.content.cloneNode(true));
this.shadowRoot.addEventListener(“slotchange”,(evt)=>{
如果(evt.target.name==“”){//
[…evt.target.assignedElements()]
.filter(el=>el.nodeName=='CHILD-ELEMENT')//处理子元素
.map(el=>el.slot=“子元素”);//强制它们到自己的插槽
}else console.log(`SLOT:${evt.target.name}get:`,evt.target.assignedNodes())
})}});
定义('child-element',类扩展HtmleElement{
connectedCallback(父元素=此.closest(“父元素”)){
//或者在此处检查并强制使用插槽名称
if(this.parentNode!=父节点){
if(parent)parent.append(this);//Child 3!!!
错误(this.innerHTML,“需要父元素!”);
}}});
子元素{color:red;display:block;}/*全局CSS中的样式lightDOM*/

:host{显示:内联块;边框:2px实心红色;}
::开槽(子元素){background:lightgreen}
分区{边框:3px紫色}
儿童1
儿童2
内容
孩子3!!!

孩子4我认为这可能是一个好问题,但就其当前形式而言,您试图实现的目标和您迄今为止成功实现的目标有点令人困惑。请您编辑/重写您的问题以使其清晰明了-我喜欢网络组件,我想帮助您解决这个问题。@Rounin,思考
slotchange
事件以获得您的答案…@Rounin我扩展了我的答案,以澄清预期结果和我迄今为止所做的尝试。@Danny'365CSI'Engelman据我所知,
slotchange
事件仅在添加或删除元素后才会在
元素上触发,但我还不知道这有助于我将它们放入正确的插槽。我猜您的意思是
childEements[I]
而不是
tabs[I]
???在这种情况下,您将不再使用
SLOT
技术,因为您现在将lightDOM内容移动到完美工作的ShadowDom。我只是想知道为什么您必须对
slotchange
事件做出反应,并且不能主动将它们移动到
,即当它们被创建或升级时或在开槽之前。是的,您可以不使用slotchange事件,并将逻辑放在子元素上:如果插槽不正确,将其设置为,因此
parent=this。最近的(“父元素”)
应该在函数体中定义。不,您可以在那里声明变量。。这是有效的JavaScript,我们不受TypeScript语法的限制。。如果组件应该很小,那么这就是防止LET语句的创建位置。。节省4个字节。请参阅我的文章中的svg()方法,所有“变量”都是“参数”,它是有效的JavaScript,在网络传输时可以节省一些字节,是的,但我的意思是DOM规范说,调用
connectedCallback()
时没有参数。把它放在参数列表中可能会让阅读你答案的人认为他们可以通过某种方式改变父母。因此,当您希望最小化代码时,这样做可能会很好,但为了清晰起见,最好在此处使用
const
语句。