0

This is actually a merge of three differents questions already all well answered here on stack overflow !

1 - How to Dynamic Load a JavaScript file from inside a Js Script :

2 - How to Dynamic Load Jquery

3 - SetTimeout inside a JS Class using this

Basically, I am building a class that will inject some pages inside my clients's website.

To do so, the client just need to add my script src on the page.

<script src="<my_pub_http_address>/MyClass.js">

Once the script is invoked, I will need jquery to continue the execution ! But, I cannot know if the website that invoked the scripts has jquery already loaded.

So, I need to check if jquery is loaded, if not, I will have to load it, append to head and only then when jquery is loaded and working, I will proceed with the script's execution .

PS: this is a kind of legacy answer ! I already had the solution beforehand ! So, any improvement will be appreciated !

Diego Favero
  • 1,613
  • 2
  • 20
  • 30
  • 1
    Why on earth would you need a class? – zer00ne May 26 '19 at 15:38
  • 1
    I'm going to guess it involves a Promise as far as how to know when jQuery has finished. But that's tricky, since your injection would really only know when the DOM injection completed, not the script loading from that DOM injection. You could have a setTimeout that just loops and checks if the jQuery object exists. But not sure how to make your class unavailable until jQuery object exists. I guess you could have a check on every method on "isReady" that returns false until jQuery has loaded. – Anthony May 26 '19 at 15:39
  • Also, what do you mean by "only then will it execute"? Is this script only expected to run once when it loads initially and not be called from anywhere else? If that's the case, just loop until it loads and then proceed. But figure out a way to do so that doesn't actually halt the entire page load, as that would be pretty rude. – Anthony May 26 '19 at 15:42
  • promises.. async / await.. this question is a non-issue – GottZ May 26 '19 at 15:46
  • @Anthony : you are corrected ... setTimeout is what I needed ... also the prepend instead append !!! – Diego Favero May 26 '19 at 15:47

1 Answers1

0

That's the solution I've found:

// MyClass.js

var counterLoopLoad = 0;

class MyClass {

    constructor(){
        // do the code that does not need jQuery
        return this.Init()
    }

    JqueryLoader() {
        // Loop Breaker
        counterLoopLoad ++;

        if (counterLoopLoad == 100) {
            throw 'I need jQuery in order to do what I am suppose to do!';
        }

        var __jquery = document.createElement('script');
        __jquery.src = "http://code.jquery.com/jquery-latest.min.js";
        __jquery.type = 'text/javascript';

        // if needed ....
        // __jquery.onload = function() {
        //     some code here
        //
        // };

        // must be prepend !!! append won't work !!!!
        document.head.prepend(__jquery);

        // here is the point that makes all work !!!!
        // without setTimeOut, the script will get in a loop !

        var that = this;
        setTimeout(function () {
            that.Init();
        }, 500);
    }

    Init() {
        if (typeof jQuery == 'undefined') {
            return this.JqueryLoader();
         }

         jQuery.ajax(...);        
    }
}
marc_s
  • 675,133
  • 158
  • 1,253
  • 1,388
Diego Favero
  • 1,613
  • 2
  • 20
  • 30
  • Why not just do `if (jQuery != defined)` – Anthony May 26 '19 at 15:46
  • 1
    Also, you shouldn't check by `$.ajax` as it's possible that even if jQuery is loaded, it isn't using the `$` object as a namespace. This can happen when other libraries already are using the `$`. If you're going to go with the ajax call, use `jQuery.ajax(...);` – Anthony May 26 '19 at 15:51
  • @Anthony . You 'r right again !!! I used the try/catch because that ajax is the only Jquery needed in this Class. Kind of I thing in this very specific case, doesn't make a difference. I will review and test the code using your tips, then I may edit the answer ! thanks ! – Diego Favero May 26 '19 at 15:52