0

For example, I want to be able to write this in HTML:

<my-container>
  Some text.
</my-container>

The JS:

class MyContainer extends HTMLElement {
  constructor() {
    super()
    const shadow = this.attachShadow({mode: 'open'})
    const p = document.createElement('p')
    shadow.appendChild(p)
  }
}

customElements.define('my-container', MyContainer)

What I end up with (though not unexpected):

<my-container>
  <p></p>
  Some text.
</my-container>

What I want:

<my-container>
  <p>Some text.</p>
</my-container>

1 Answers1

0

HTML in Custom Elements with shadowDOM remains (invisible) in lightDOM

You either move it yourself:

<my-element>
  Hello World, I came from lightDOM
</my-element>

<script>
  customElements.define("my-element", class extends HTMLElement {
    constructor() {
      super().attachShadow({
        mode: 'open'
      }); // sets and returns thi.shadowRoot for free
      this.wrapper = this.shadowRoot.appendChild(document.createElement('H1'));
      this.wrapper.innerHTML = "please click me";
    }
    connectedCallback() {
      this.onclick = () => this.wrapper.innerHTML = this.innerHTML;
    }
  });
</script>

Or you use shadowDOM SLOTs

<style>
 my-element{
  color:green;
 }
</style>
<my-element>
  Hello World, I am REFLECTED from lightDOM
</my-element>

<script>
  customElements.define("my-element", class extends HTMLElement {
    constructor() {
      super().attachShadow({
        mode: 'open'
      }); // sets and returns thi.shadowRoot for free
      this.wrapper = this.shadowRoot.appendChild(document.createElement('H1'));
      this.wrapper.innerHTML = "<slot></slot";
    }
    connectedCallback() {
    }
  });
</script>

Note how content is styled!

The text/html remains IN lightDOM, it is reflected IN shadowDOM

Do read: ::slotted CSS selector for nested children in shadowDOM slot

Danny '365CSI' Engelman
  • 16,526
  • 2
  • 32
  • 49