Search code examples
javascriptweb-componentcustom-element

Use document in custom element (web component)


I have two separate custom element components and if I want to do something with the ComponentB's element inside of ComponentA, what is the best way to do it?

index.html

<body>

  <componentA>
    <div class="container">
     <p>I am component A</p>
     <p>abc</p>
    </div>
  </componentA>

  <componentB>
    <div class="container">
     <p>I am component B</p>
     <p></p> // Will set data between the p tag in componentA
    </div>
  </componentB>

</body>

componentA.js

...component template...

class ComponentA extends HTMLElement {

  constructor() {
    super();
    this.attachShadow({mode: 'open'});
    this.shadowRoot.appendChild(template.content.cloneNode(true));
  }

  connectedCallback() {

    this.setInnerTextToComponentBElement();

  }

  setInnerTextToComponentBElement(){

    // How to set componentB's second p tag innerText?

  }
}

customElements.define('componentA', ComponentA );

I have thought of using document.querySelector to get the componentB element and go from there... but is this the best practice way to do it?


Solution

  • I would suggest NEVER tying two components together without allowing the developer using the components to provide a way to connect them.

    Normally communications or interconnections between elements is handled by the parent. The only element that I know of that does this by itself is the <label> element. If this is the parent of an <input>, <select>, <button> or <textarea> then it will pass its focus on to the child element.

    But to use it with a sibling element you have to set the for attribute of the <label> to be the id of the other field. And then the other field needs to have its id set.

    I answered something like this here: How to communicate between Web Components (native UI)?

    Once you tie two components together these components are no longer usable by themselves unless you write extra code to allow separation.

    Instead, either allow the components to dispatch events that the parent will receive and the parent will then pass values on to the other component. Or, follow the example of how <label for=""> works.