Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event when web component has loaded

I have a web component like this

<template id="component">
    <link href="/static/css/main.cacbacc7.css" rel="stylesheet">
    <script src="/static/js/vendor.js" type="text/javascript"></script>
    <script src="/static/js/bundle.js" type="text/javascript"></script>
    <span id="react-app"></span>
</template>

<script>
  (function (window, document) {
    const doc = (document._currentScript || document.currentScript).ownerDocument;
    const proto = Object.create(HTMLElement.prototype, {
      attachedCallback: {
        value: function () {
          const template = doc.querySelector('template#component').content;
          const shadowRoot = this.attachShadow({ mode: 'open' });
          shadowRoot.appendChild(template.cloneNode(true));
          // executeThis() when all scripts have been loaded
        }
      },
    });
    document.registerElement('react-webcomponent', { prototype: proto });
  })(window, document);
</script>

Can I know when all script tags in my template have been loaded?

Update

What I am currently doing is

const scripts = [...shadowRoot.querySelectorAll('script')];
let scriptsLoaded = 0;
scripts.forEach(function (script) {
  script.addEventListener('load', function () {
    if (++scriptsLoaded >= scripts.length) {
      LoadReactAppIntoShadowDomContainer(shadowRoot.querySelector('#react-app'));
    }
  })
});

But I am hoping for a nicer way.

About the possible duplicate: Will it work for web components?

like image 886
Lukas Avatar asked Aug 07 '17 11:08

Lukas


People also ask

Which event triggers when object is loaded?

onload. The load event on the window object triggers when the whole page is loaded including styles, images and other resources. This event is available via the onload property.

Which event would you use to start a script after a page has been fully loaded by the browser?

The onload event occurs when an object has been loaded. onload is most often used within the <body> element to execute a script once a web page has completely loaded all content (including images, script files, CSS files, etc.).

When to use DOM content loaded?

DOMContentLoaded is a great event to use to hookup UI functionality to complex web pages. The DOMContentLoaded event is fired when the document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading (the load event can be used to detect a fully-loaded page).

How do you know if a page is fully loaded?

You can check the document. readyState property. From MDN: Returns "loading" while the document is loading, "interactive" once it is finished parsing but still loading sub-resources, and "complete" once it has loaded.


1 Answers

Your update example is the best way I know of.

I had a similar issue looking to prevent FOUC on my components that were importing CSS via tags.

The only solution I could find is as per your update. QS the ShadowRoot to find the <link> or <scripts>, add a load event listener to each and compare the load count.

The one optimisation you might consider, is when the count matches you can dispatch your own custom load event from the shadow root itself, that a listener on your component shadow root (or further up the tree) can handle.

var event = new CustomEvent('load');
shadowRoot.dispatchEvent(event);

If you want it to bubble up and cross the shadow boundary you'll need to add composed : true to the event args.

var event = new CustomEvent('load', {bubbles : true, composed : true});
shadowRoot.dispatchEvent(event);
like image 188
Neil Avatar answered Oct 19 '22 02:10

Neil