Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch 22: Load Script if Element That Depends on Script Exists

My goal is to load javascript in the <head> only if a certain element exists in the <body>.

However, I have a problem: I am loading a Web Component, which is just a <script> hosted elsewhere and is pulled in as:

<script src="https://someurl.com/some-web-component.min.js"></script>

This web component file is huge, so I don't want to pull it in unless it is inserted into body by our Content Management System (CMS).

The constraints I am working under are:

• The <head> is shared between pages, so I need conditional logic

• I have no control over the <body> inserted by the CMS, which will potentially contain the <my-web-component> tag

• I NEED the script to load the web component, so I can't use jQuery's $(document).ready, at least I think I can't - an error will be thrown because the browser won't know the element exists

This plunker partially shows my problem, minus all the web component complexity:

https://plnkr.co/edit/GGif2RNHX1iLAvSk1nUw?utm_source=next&utm_medium=banner&utm_campaign=next&p=preview

Any way around this?

like image 316
VSO Avatar asked May 11 '26 19:05

VSO


1 Answers

You can use DOMContentLoaded event.

The DOMContentLoaded event is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.

In this case you can look for the Component and add the script with something like the following

document.addEventListener("DOMContentLoaded", function(event) {
  if(document.querySelector('Component')){
    var script = document.createElement('script');
    script.src = 'https://someurl.com/some-web-component.min.js';
    document.head.appendChild(script)
  }
});

Probably a better approach though would be to add the script in the head with async attribute and later remove it if the component is not found. Something like this

<script async src = "https://someurl.com/some-web-component.min.js"> </script> 
<script >
  document.addEventListener("DOMContentLoaded", function(event) {
    if (document.querySelector('Component') == null) {
      var script = document.querySelector('script[src="https://someurl.com/some-web-component.min.js"]')
      document.head.removeChild(script)
    }
  }); 
</script>

More about DOM lifecycle events
More about async script loading

like image 146
Moti Korets Avatar answered May 13 '26 08:05

Moti Korets