Loading (Web Components)

Demo

Show (5 sec) Change Color to DARKRED
let ls = document.querySelector('loading-screen');
document.querySelector('#btn-show')
  .addEventListener('click', function () {
    ls.setAttribute('opened', '');
    setInterval(function () {
      ls.removeAttribute('opened')
    }, 5000);
  });
document.querySelector('#btn-change-color')
  .addEventListener('click', function () {
    ls.setAttribute('color', 'darkred');
    ls.setAttribute('opened', '');
    setInterval(function () {
      ls.removeAttribute('opened')
    }, 5000);
  });

HTML

<loading-screen color="LIGHTSLATEGRAY"></loading-screen>

Attributes:

JS

class loadingScreen extends HTMLElement {
    constructor() {
      super();

      const _shadowdomAccessibilityFromDom = 'open';
      this.attachShadow({
        mode: _shadowdomAccessibilityFromDom
      });
      this.shadowRoot.innerHTML = `
        <style>
          :host {
            background-color: rgba(255, 255, 255, 0.85);
            display: flex;
            justify-content: center;
            align-items: center;
            position: fixed;
            top: 0px;
            left: 0px;
            height: 100vh;
            width: 100vw;
            z-index: 1010;
            transition: opacity .5s ease-in-out;
            opacity: 0;
            pointer-events: none;
          }
          
          :host([opened]) {
            opacity: 1;
            pointer-events: all;
          }

          .icon {
            border-radius: 50%;
            border-style: solid;
            border-width: 10px;
            border-color: transparent;
            width: 120px;
            height: 120px;
          }
          
          .spin {
            animation: spin 2s linear infinite both;
          }
      
          @keyframes spin {
            0% {transform: rotate(0)}
            100% {transform: rotate(360deg)}
          }      
        </style>
        <div class="icon spin"></div>
      `;
    };

    connectedCallback() { };

    static get observedAttributes() { return ['color']; }

    attributeChangedCallback(name, oldValue, newValue) {
      if (oldValue === newValue) {
        return
      }
      if (name === 'color') {
        this._setColor(newValue)
      }
    }

    _setColor(color) {
      this.shadowRoot.querySelector('.icon').style.borderBottomColor = color;
    };
  }

  customElements.define('loading-screen', loadingScreen);