最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Composing v1 nested web components - Stack Overflow

programmeradmin0浏览0评论

I'm new to webcomponents. Since v1 of webcomponents is available, I'm starting there. I have read various posts around the web about them. I'm particularly interested in composing them correctly. I have read about slots and have them working, although my efforts have not resulted in slotted webcomponents that work the way I expected.

If I have compose nested web components like this, the DOM from the nested/slotted webcomponent does not get inserted in the slot of the parent:

<parent-component>
  <child-component slot="child"></child-component>
</parent-component>

I'm new to webcomponents. Since v1 of webcomponents is available, I'm starting there. I have read various posts around the web about them. I'm particularly interested in composing them correctly. I have read about slots and have them working, although my efforts have not resulted in slotted webcomponents that work the way I expected.

If I have compose nested web components like this, the DOM from the nested/slotted webcomponent does not get inserted in the slot of the parent:

<parent-component>
  <child-component slot="child"></child-component>
</parent-component>

And here's the parent webcomponent HTML:

<div id="civ">
  <style>
  </style>
  <slot id="slot1" name="child"></slot>
</div>

Since each webcomponent (parent and child) is written to be independent, I have been creating them with:

customElements.define('component-name', class extends HTMLElement {
  constructor() {
    super();
    this.shadowRoot = this.attachShadow({mode: 'open'});
    this.shadowRoot.innerHTML = `HTML markup`
  }
})

The resulting DOM includes 2 shadow roots. I have attempted to write child/slotted elements without shadow dom, which also does not result in the parent shadow dom hosting the children.

So, what is the right way to compose v1 nested webcomponents?

Share Improve this question edited Mar 31, 2021 at 19:00 Crono 10.5k6 gold badges45 silver badges80 bronze badges asked Aug 16, 2016 at 13:54 rob_hicksrob_hicks 1,7343 gold badges24 silver badges35 bronze badges 0
Add a comment  | 

1 Answer 1

Reset to default 17

First, you must use a browser that implements Shadow DOM and Custom Elements v1.

Then the call to attachShadow() will assign the new Shadow DOM automatically to the read-only property shadowRoot.

You can append the HTML code to the Shadow DOM's innerHTML but I'd recommend to use a <template>'s content property instead.

Then nesting is natural:

customElements.define( 'parent-component', class extends HTMLElement {
    constructor() {
        super()
        this.attachShadow( {mode: 'open'} )
        this.shadowRoot.appendChild( parent1.content.cloneNode( true ) )
    }
} )
            
customElements.define( 'child-component', class extends HTMLElement {
    constructor() {
        super()
        var sh = this.attachShadow( {mode: 'open'} )
        sh.appendChild( child1.content.cloneNode( true ) )
    }
} )
<parent-component>
    <child-component slot="child">
        <span>Hello</span>
    </child-component>
</parent-component>


<template id="parent1">
    <style>
        :host { background: lightblue ; display: inline-block }
        ::slotted( [slot=child] ) { background: lightyellow }
    </style>
    <h4>(parent)</h4>
    <p>Slotted child:
        <slot name="child"></slot>
    </p>
</template>    

<template id="child1">
    <style>
        :host { display: inline-block }
        ::slotted( span ) { background: pink }
    </style>
    <h5>(child)</h5>
    <span>Nested slot: <slot></slot></span>
</template>

In the <style> tags, use:

  • :host to style the custom element itself, and
  • ::slotted() to style the elements inserted with a <slot> tag.
发布评论

评论列表(0)

  1. 暂无评论