Search code examples
javascriptcustom-element

connectedCallback vs window.load


What event comes first if custom element is included in plain HTML body?

const elem = document.getElementById('test');

window.addEventListener('load', () => {
  elem.innerHTML = 'window.load';
});

class myDiv extends HTMLElement {
  connectedCallback() {
    elem.innerHTML = 'connectedCallback';
  }
}

customElements.define('my-div', myDiv);
<my-div id="test"></my-div>

Looks like window.load always comes last.


Solution

  • As was stated by @zer00ne the general rule is that windows.onload is called last as long as everything is already on the page.

    If you create elements dynamically then their constructor and connectedCallback functions will be called after window.onload.

    Also if you lazy load any of your components then they will run after window.onload even if you place their HTML in the page prior to the trigger of window.onload.

        const loaded = msg => () => console.log(msg);
    
        window.onload = loaded('window.onload');
    
        class MyEl extends HTMLElement {
          constructor() {
            super();
            loaded('MyEl.constructor')();
          }
    
          connectedCallback() {
            loaded('MyEl.connectedCallback')();
          }
        }
    
        customElements.define('my-el', MyEl);
    
        setTimeout(()=>{
          console.log('About to create element');
          var newEl = document.createElement('my-el');
          console.log('About to add element to body');
          document.body.appendChild(newEl);
        }, 1000);
        setTimeout(()=>{
          console.log('About to create new script tag');
          newEl = document.createElement('script');
          newEl.textContent = `
          class MyEl2 extends HTMLElement {
            constructor() {
              super();
              loaded('MyEl2.constructor')();
            }
    
            connectedCallback() {
              loaded('MyEl2.connectedCallback')();
            }
          }
    
          customElements.define('my-el-2', MyEl2);
          `;
          console.log('About to add script element to body');
          document.body.appendChild(newEl);
        }, 2000);
        <my-el></my-el>
        <my-el-2></my-el-2>