Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 11 of 11
  1. #1
    New Coder
    Join Date
    Apr 2005
    Location
    Massachusetts, US
    Posts
    37
    Thanks
    5
    Thanked 0 Times in 0 Posts

    Best way to test for a script load

    This is related to my previous post yesterday, but this issue is different than the one that post was about, so I decided to make a new thread. If they need to be merged, please feel free.

    So, I wrote this function to load up a JS file hosted on my remote web server into the DOM (this is for a Firefox extension if you're wondering why).
    Code:
      function loadScript(scriptURL) {
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = scriptURL;
        head.appendChild(script);
    
        // Function to check if the JS has been loaded yet
        function waitForLoad() {
          if(typeof testFunction != 'function') {
            var t=setTimeout("waitForLoad()",100);
          } else {
              return true;
          }
        } // waitForLoad
    
        waitForLoad();
      } // loadScript
    'rnd me' gave an example where I could use a local variable at the end of the script instead of a testFunction(), and just check to see if that variable is initialized instead. I was planning on changing it to do this, but figured I should wait until I see what people say about this.

    Anyways, so that code above works 100% fine. The problem comes from my having to use this loadScript function to inject nine scripts. This means that the test case in waitForLoad() is broken.

    Does anyone know a way that I can use to check if a script has been loaded, that does not depend on a certain method or variable within the script? Or maybe someone can suggest just any way of going about doing this?

    Any help would be appreciated
    Last edited by Forever Zero; 06-19-2008 at 06:59 PM.

  • #2
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    1) I think your scripts are loaded synchronously. That is, they will load in the order that your code loads them (after the current script is finished loaded). In that case, after you load all your scripts, load an extra "helper" script, and have him do the magic, since the others will have to be loaded by the time he is loaded. Try this, I think it will work. Aka:

    Code:
    // loader script file.
    
    importScript("abc.js");
    importScript("def.js");
    importScript("ghi.js");
    importScript("mainScript.js");
    2) Use AJAX (I'm no expert at it though).
    Last edited by Trinithis; 06-19-2008 at 07:57 PM.
    Trinithis

  • #3
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    I made this a long while ago. Not sure if it is good ajax scripting, but who knows. If I remember correctly, it worked for me.

    Code:
    var Importer = {
      importedFiles: {},
      protocol: /^\s*\w+:\/\//,
      ajaxWarning: "Your browser does not support AJAX.\nYou can update your browser to get AJAX support.",
      directory: window.location.href.replace(/[^\/\\]+$/, ""),
      include: function(uri) {
        if(!this.protocol.test(uri))
          uri = this.directory + uri;
        if(this.importedFiles[uri])
          return;
        this.importedFiles[uri] = true;
        var req = window.XMLHttpRequest
          ? new XMLHttpRequest()
          : new ActiveXObject("Microsoft.XMLHTTP");
        if(!req) {
          if(this.ajaxWarning !== false)
            alert(this.ajaxWarning);
          this.ajaxWarning = false;
          return;
        }
        req.open("GET", uri, false);
        req.send(null);
        if(!window.execScript)
          window.eval(req.responseText);
        else
          window.execScript(req.responseText);
      }
    };
    Usage:
    Code:
    Importer.load("abc.js");
    abcFunc1();
    Importer.load("def.js");
    Importer.load("ghi.js");
    defFunc10();
    ghiFunc4();
    Trinithis

  • Users who have thanked Trinithis for this post:

    Forever Zero (06-19-2008)

  • #4
    New Coder
    Join Date
    Apr 2005
    Location
    Massachusetts, US
    Posts
    37
    Thanks
    5
    Thanked 0 Times in 0 Posts
    Thanks, that's really good to know.

    What I got from what you said is that since they are loaded synchronously, I only need to run the waitForLoad() function on the very last script. Is that about right?

    Also, about the AJAX, I would actually much rather do this, but the problem is that AJAX doesn't seem to support cross-domains. This script is for a Firefox extension I am writing, where it needs to inject some JS files to make highlighted words pop up a window when you hover over it that requires a load of JS files.

    It might be possible though, maybe I should head on over to the AJAX forum :P

    EDIT: Woah just saw your second post. I actually tried something like that first thing, but it kept giving me permissions denied errors. Is that code you posted able to take JS files off of either a local machine or a remote server and load them up on the current page? If it can, that would be amazing haha.

    Thanks again!
    Last edited by Forever Zero; 06-19-2008 at 08:05 PM.

  • #5
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    It was able to import files from my own computer, but when I tried using it to import a script from a (free) host, the host denied it. If this is just for personal use, then it should work fine if you store all your files on your own computer.

    I'm not sure if it would suit your purposes, but have you heard of Greasemonkey?
    Trinithis

  • #6
    New Coder
    Join Date
    Apr 2005
    Location
    Massachusetts, US
    Posts
    37
    Thanks
    5
    Thanked 0 Times in 0 Posts
    If this can import files from your computer that is actually even better.

    I was actually looking at the Greasemonkey source to try and see how they did it, but it was mind boggling for me haha (just started learning JS a week ago). One of their developers was nice enough to give me some answers, but I didn't want to bog them down with endless questions haha.

    I'm gonna try out the AJAX script you posted and post the result in this thread after I mess around with it some.

  • #7
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    Just be sure to change the default directory value if it isn't appropriate. It defaults to the directory of the Importer.js (or whatever you put it in).
    Code:
    Importer.directory = "dir1";
    // do some loading
    Importer.directory = "dir2";
    // do some more loading
     . . .
    Trinithis

  • #8
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,333
    Thanks
    11
    Thanked 587 Times in 568 Posts
    i use:
    Code:
        function JSget(turl) {
            var xJs = document.createElement("script");
            xJs.type = "text/javascript";
            var h = document.getElementsByTagName("head");
            if (h && h[0]) {
                h[0].appendChild(xJs);
            }
            xJs.src = turl;
            return xJs;
        }

    it works from any domain anywhere. (http:, https:, file:, data: )

    you dont even need to wait for the last script, your browser will anyway. in other words, you shouldnt have to test for it.

    further, you can put code in the body, and all the code in the head will be loaded and executed before it finds body scripts.
    Last edited by rnd me; 06-19-2008 at 10:01 PM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%

  • Users who have thanked rnd me for this post:

    Forever Zero (06-20-2008)

  • #9
    New Coder
    Join Date
    Apr 2005
    Location
    Massachusetts, US
    Posts
    37
    Thanks
    5
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by rnd me View Post
    i use:
    Code:
        function JSget(turl) {
            var xJs = document.createElement("script");
            xJs.type = "text/javascript";
            var h = document.getElementsByTagName("head");
            if (h && h[0]) {
                h[0].appendChild(xJs);
            }
            xJs.src = turl;
            return xJs;
        }

    it works from any domain anywhere. (http:, https:, file:, data: )

    you dont even need to wait for the last script, your browser will anyway. in other words, you shouldnt have to test for it.

    further, you can put code in the body, and all the code in the head will be loaded and executed before it finds body scripts.
    This worked perfectly, thank you! You've been really helpful

    Quote Originally Posted by Trinithis View Post
    I made this a long while ago. Not sure if it is good ajax scripting, but who knows. If I remember correctly, it worked for me.

    Code:
    var Importer = {
      importedFiles: {},
      protocol: /^\s*\w+:\/\//,
      ajaxWarning: "Your browser does not support AJAX.\nYou can update your browser to get AJAX support.",
      directory: window.location.href.replace(/[^\/\\]+$/, ""),
      include: function(uri) {
        if(!this.protocol.test(uri))
          uri = this.directory + uri;
        if(this.importedFiles[uri])
          return;
        this.importedFiles[uri] = true;
        var req = window.XMLHttpRequest
          ? new XMLHttpRequest()
          : new ActiveXObject("Microsoft.XMLHTTP");
        if(!req) {
          if(this.ajaxWarning !== false)
            alert(this.ajaxWarning);
          this.ajaxWarning = false;
          return;
        }
        req.open("GET", uri, false);
        req.send(null);
        if(!window.execScript)
          window.eval(req.responseText);
        else
          window.execScript(req.responseText);
      }
    };
    Usage:
    Code:
    Importer.load("abc.js");
    abcFunc1();
    Importer.load("def.js");
    Importer.load("ghi.js");
    defFunc10();
    ghiFunc4();
    I still want to try this out because I've been curious about AJAX for some time now. I have a few questions on that...

    1. I saw you said the usage was Importer.load("blah.js"), where exactly is the load function in that script? Do you mean that I should create my own function called load and warp it around that? I also noticed that it gets the uri by passing it through what (looks to me like) an unnamed function: "include: function(uri) {" but I am still unsure how exactly the script obtains the uri to use.

    2. What exactly is "protocol" here? protocol: /^\s*\w+:\/\//
    Also, I noticed a lot of lines like that (that use a colon instead of equals), is this how you declare a variable inside an object? Or is that the syntax for something else?

    3. I'm guessing that these lines here check for IE, but could you please clarify it?
    Code:
        var req = window.XMLHttpRequest
          ? new XMLHttpRequest()
          : new ActiveXObject("Microsoft.XMLHTTP");
    I'll be messing around with it still, but I want to make sure that I fully understand the stuff I'm using .

  • #10
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    1. Whoops. I the usage should be Importer.include, not Importer.load.

    2. The protocol regex (not sure if its a good name for it) tests whether or not the file you are importing has a relative or an absolute path. If it has an absolute path, everything's okay. Otherwise, it tacks on the directory path to the beginning of the filename.

    It does this by looking for things like http://, ftp://, file://, etc.

    3.
    Code:
    var req = window.XMLHttpRequest
      ? new XMLHttpRequest()
      : new ActiveXObject("Microsoft.XMLHTTP");
    IE (as we all know) is a piece of crap and does not conform to conventions. Instead of having XMLHttpRequest, it uses ActiveXObject.
    Trinithis

  • #11
    New Coder
    Join Date
    Apr 2005
    Location
    Massachusetts, US
    Posts
    37
    Thanks
    5
    Thanked 0 Times in 0 Posts
    Hey,

    just wanted to say that I got your script working perfectly. I couldn't get it to do cross domain requests, but apparently if you call an XMLhttpRequest from inside a chrome window, it can go cross domain (go figure).

    Thanks again for your help

    EDIT: And for the record, yes, IE is a piece of crap
    Last edited by Forever Zero; 06-24-2008 at 02:45 PM.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •