Search code examples
htmltypescriptweb-componentlit-elementlit

How to get inner content as a variable without rendering in LitElements


I am using my lit element like this

<my-header>MyHeading</my-header>

And I have my lit element's render method:

render() {
  return html`
    <h3><slot></slot></h3>
  `;
}

which is working perfectly. Now I want the inner content i.e. "MyHeading" in my lit element's class as a value(not to render). Is there any way to get that innerHTML or as a text?

Note: my use case can be to set another property of rendered content like

render() {
  return html`
    <h3 id="${//How to get that 'MyHeading' here??}"><slot></slot></h3>
  `;
}

Is it possible to get inner content as a value?


Solution

  • This is what you get when you learn new stuff starting with a Library or Framework;
    You learn the Tool, not the Technology.

    The child-elements of your customElement are not available yet
    when the connectedCallback fires

    • so you wait till the EventLoop is empty (and thus know all children are parsed)

    • Or use any of the Library methods that (usually) fire even later than a setTimeout

    • Or, even more blunty, like many blogs show, execute the script that creates your Element
      after the whole DOM is parsed by marking it a type="module" or async or defer

    <script>
      customElements.define("my-element", class extends HTMLElement {
        constructor(){
            super().attachShadow({mode:"open"}).innerHTML = `<h3><slot></slot></h3>`
        }
        connectedCallback() {
          setTimeout(() => { // wait till innerHTML is parsed
            let title = this.innerText;
            console.log("Reflected from lightDOM:" , title);
            this.shadowRoot.querySelector("h3").id = title;
          })
        }
      })
    </script>
    
    <my-element>
      Hello Web Components!
    </my-element>