{TametheBots}

Web Components / Shadow DOM

The Result - Slotted:

This is the stuff in the slot

The Result - <template>:

This is the stuff in the template slot

The Result - Nested:

This is the stuff in the inner slot

The Result - Attributes:

The Result - Fetch:

Attribute Hardcoded: Expected: Test phrase 1

Attribute set via script: Expected: Test phrase 2

The Result - Closed Shadow Root:

Code

In head

    <script>
    class TtbTestComponentSlotted extends HTMLElement {
      constructor() {
        super();
        this.attachShadow({ mode: 'open' });
      }
      connectedCallback() {
        let p = document.createElement('p');
        p.innerHTML = 'This is the stuff in JS. <slot></slot> <a href="hiddenpage.html">Link only in web component</a>';
        this.shadowRoot.appendChild(p);
      }
    }
    window.customElements.define('ttb-test-component-slotted', TtbTestComponentSlotted);

    class TtbTestComponentWrapper extends HTMLElement {
      constructor() {
        super();
        this.attachShadow({ mode: 'open' });
      }
      connectedCallback() {
        let div = document.createElement('div');
        div.innerHTML = '<p>This text is in the wrapper component</p><slot></slot>';
        this.shadowRoot.appendChild(div);
      }
    }
    window.customElements.define('ttb-test-component-wrapper', TtbTestComponentWrapper);

    class TtbTestComponentInner extends HTMLElement {
      constructor() {
        super();
        this.attachShadow({ mode: 'open' });
      }
      connectedCallback() {
        let p = document.createElement('p');
        p.innerHTML = '<p>This text is in the inner component</p><slot></slot>';
        this.shadowRoot.appendChild(p);
      }
    }
    window.customElements.define('ttb-test-component-inner', TtbTestComponentInner);


    class TtbTestComponent extends HTMLElement {
      constructor() {
        super();
        this.attachShadow({ mode: 'open' });
      }
      connectedCallback() {
        let p = document.createElement('p');
        let theText;
        if (this.hasAttribute('text')) {
          theText = this.getAttribute('text');
        } else {
          theText = "Attributes not passed"
        }
        p.innerHTML = theText;
        this.shadowRoot.appendChild(p);
      }
    }
    window.customElements.define('ttb-test-component', TtbTestComponent);

    class TtbTestComponentFetch extends HTMLElement {
      constructor() {
        super();
        this.attachShadow({ mode: 'open' });
      }
      connectedCallback() {
        let p = document.createElement('p');
        let theText;
        if (this.hasAttribute('index')) {
          try {
            const request = async () => {
              const response = await fetch('test.json');
              const json = await response.json();
              theText = json[parseInt(this.getAttribute('index'))].phrase;
              p.innerHTML = '<strong>' + theText + '</strong>';
            }
            request();
          } catch (error) {
            theText = 'Error:', error;
            p.innerHTML = '<strong>' + theText + '</strong>';
          }
        } else {
          theText = "Attributes not passed"
          p.innerHTML = '<strong>' + theText + '</strong>';
        }

        this.shadowRoot.appendChild(p);
      }
    }
    window.customElements.define('ttb-test-component-fetch', TtbTestComponentFetch);

    class TtbClosedComponent extends HTMLElement {
      constructor() {
        super();
        this._root = this.attachShadow({ mode: "closed" });
      }
      connectedCallback() {
        this._root.innerHTML = `
            <p>Output from a <strong>closed</strong> Shadow Root.</p>
        `;
      }
    }
    window.customElements.define("ttb-closed-component", TtbClosedComponent);

    class TtbTemplateComponent extends HTMLElement {
      constructor() {
        super();
        let template = document.getElementById('aTemplate');
        let templateContent = template.content;

        const shadowRoot = this.attachShadow({ mode: 'open' })
          .appendChild(templateContent.cloneNode(true));
      }
    }
    window.customElements.define("ttb-template-component", TtbTemplateComponent);
  </script>
        

Body:

    <template id="aTemplate">
    <style>
      p {
        color: white;
        background-color: #666;
        padding: 5px;
      }
    </style>
    <div>
      <p>This is in the template</p>
      <slot></slot>
    </div>
  </template>
  <div class="aligner">
    <div class="aligner-item">
      <h1>{Tame<span class="red">the</span>Bots}</h1>
      <h2>Web Components / Shadow DOM</h2>
      <h3>The Result - <span class="red">Slotted</span>:</h3>
      <ttb-test-component-slotted><strong>This is the stuff in the slot</strong></ttb-test-component-slotted>
      <h3>The Result - <span class="red">&lt;template&gt;</span>:</h3>
      <ttb-template-component>
        <p>This is the stuff in the template slot</p>
      </ttb-template-component>
      <h3>The Result - <span class="red">Nested</span>:</h3>
      <ttb-test-component-wrapper>
        <ttb-test-component-inner>
          <p><em>This is the stuff in the inner slot</em></p>
        </ttb-test-component-inner>
      </ttb-test-component-wrapper>
      <h3>The Result - <span class="red">Attributes</span>:</h3>
      <ttb-test-component text="This is passed through attributes."></ttb-test-component>
      <h3>The Result - <span class="red">Fetch</span>:</h3>
      <p>Attribute Hardcoded: <em>Expected: Test phrase 1</em></p>
      <ttb-test-component-fetch index="0"></ttb-test-component-fetch>
      <p>Attribute set via script: <em>Expected: Test phrase 2</em></p>
      <ttb-test-component-fetch index="" id="fetchComp"></ttb-test-component-fetch>
      <h3>The Result - <span class="red">Closed Shadow Root</span>:</h3>
      <ttb-closed-component></ttb-closed-component>
        

< Back