1

I use an include function to dynamically include javascript files/headers/libraries.

The problem is that it seems loading the file happens in a multi-threaded way (tested on Chrome v102) and the js file is not yet loaded when I immetiately use functionnality after that.

Example with jQuery:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf8"/>
        <script type="text/javascript">
            var include_once = function(url) {
                /*
                [additional code to check if 'url' was already included]
                */
                var script = document.createElement("script");
                script.type = "text/javascript";
                script.src = url;
                document.head.appendChild(script);
            }
            
            include_once("https://code.jquery.com/jquery-3.6.0.min.js");
        </script>
    </head>
    <body>
        <script type="text/javascript">
            /*
            ok if I wait 'long enough' but is arbitrary
            */
            setTimeout(function(){
                $(document).ready(function(){
                    console.log("ready (timeout)");
                });
            }, 10);
            
            /*
            how to wait until window.$ is defined?
            */
            $(document).ready(function(){
                console.log("ready");
            });
        </script>
    </body>
</html>

This code will likely give you a $ is not defined error, and ready (timeout) will be logged to the console.

How can I make my script wait until window.$ !== undefined here ?

I tried while(window.$ === undefined) {} but it completely blocks the script and $ is never defined.

6
  • 1
    See developer.mozilla.org/en-US/docs/Web/API/… Commented Jun 4, 2022 at 11:20
  • @mplungjan it does work with a timeout. Test it. Commented Jun 4, 2022 at 11:21
  • let script = document.createElement("script"); script.type = "text/javascript"; script.addEventListener("load", function() { console.log(`${url} loaded`) }); script.src = url; document.head.appendChild(script); Commented Jun 4, 2022 at 11:24
  • 1
    You can easily achieve both targets with querySelector and promises jsfiddle.net/c7a1u6td Commented Jun 4, 2022 at 11:35
  • @Christopher can you explain what the regexp does please? Commented Jun 4, 2022 at 12:13

1 Answer 1

1

you can promisfy the loading process, by creating a promise on first script and then on the second script check if the promise is resolved.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf8"/>
        <script type="text/javascript">
            var isLoaded = new Promise((res,rej) => {
              function include_once(url) {
                  /*
                  [additional code to check if 'url' was already included]
                  */
                  var script = document.createElement("script");
                  script.type = "text/javascript";
                  script.onload = () => res()
                  script.onerror = () => rej()
                  script.src = url;
                  document.head.appendChild(script);
              }
              include_once("https://code.jquery.com/jquery-3.6.0.min.js");
          })
          
        </script>
    </head>
    <body>
        <script type="text/javascript">
            isLoaded.then(() => {
              $(document).ready(function(){
                console.log("ready");
            });
            })
        </script>
    </body>
</html>

Sign up to request clarification or add additional context in comments.

1 Comment

I never used Promise before but that's interesting- thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.