unj2
unj2

Reputation: 53521

Internet Explorer tries to run jQuery before loading the library

I have a small script

document.write("<html><head><script src='/js/jquery-1.4.2.min.js' type='text/javascript'></scr"
         + "ipt><script>alert($"+"().jquery);</scri" + "pt></head></html>");

But I get a $ is undefined in Internet Explorer. I think it tries to run the script before loading the library.

However this runs in Firefox. Please help.

Edit: I open a new window and write to that window's document.

Upvotes: 3

Views: 3171

Answers (11)

Praveen Prasad
Praveen Prasad

Reputation: 32117

you are just creating a tag to reference jQuery, and as soon as its created next statement is an alert. There is no way specified by you that alert statement should run after after file load.

Upvotes: 0

Dr.Molle
Dr.Molle

Reputation: 117354

See this solution: JavaScript's document.write Inline Script Execution Order

(also note the comment, it's important)

Upvotes: 1

gion_13
gion_13

Reputation: 41533

try running your second script on page load(window.onload) , or try inserting the script in the body, not in the head section.
try :

document.write("<html><head><script src='/js/jquery-1.4.2.min.js' type='text/javascript'></scr"
     + "ipt><script>window.onload = function(){alert($"+"().jquery);};</scri" + "pt></head></html>");

the browser won't load the library instantly (unless it has it in its cache) so your script might get called before the library is loaded.

Upvotes: 1

Greg Pettit
Greg Pettit

Reputation: 10830

If you want simplified conditional loading of jQuery, there are many options out there already; no need to reinvent the wheel. Already mentioned are RequireJS and LabJS. I am using Head.js and it couldn't be easier to accomplish the goal of non-blocking loading while respecting execution order.

Upvotes: 0

Jannes Meyer
Jannes Meyer

Reputation: 1248

The thing is that you have unintentionally triggered IE to load your scripts in a non-blocking way. Read this for more information: Loading JavaScript without blocking.

The page suggests that you use this code to get notified when the script has finished loading:

//Internet Explorer only
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "/js/jquery-1.4.2.min.js";
script.onreadystatechange = function(){
    if (script.readyState == "loaded" ||
            script.readyState == "complete"){
        script.onreadystatechange = null;
        // Your code goes here.
        alert("Script is ready!");
    }
};
document.body.appendChild(script);

Upvotes: 4

madr
madr

Reputation: 665

A simple timer should do it.

(function(){
  function wait() {
    if (typeof jQuery == 'undefined') {
        setTimeout(wait, 50);            
    } else {
        run(); // your code to execute
    }
  }

  wait();
})();

Example on jsfiddle: http://jsfiddle.net/madr/Gtafq/

Upvotes: -1

ken
ken

Reputation: 3709

Give this a try?

http://jsfiddle.net/MP75r/

Upvotes: 0

NT3RP
NT3RP

Reputation: 15370

Have you tried moving the script tag running your code to the end of the body tag? According to Yahoo's best practices (creators of YSlow):

The problem caused by scripts is that they block parallel downloads. The HTTP/1.1 specification suggests that browsers download no more than two components in parallel per hostname. If you serve your images from multiple hostnames, you can get more than two downloads to occur in parallel. While a script is downloading, however, the browser won't start any other downloads, even on different hostnames.

So the result would look like...

document.write("<html><head><script src='/js/jquery-1.4.2.min.js' type='text/javascript'></scr"
     + "ipt></head><body><script>alert($"+"().jquery);</scri" + "pt></body></html>");

Although I would also advocate not using document.write().

Upvotes: 0

gonchuki
gonchuki

Reputation: 4124

What's wrong with creating the <script> tag the proper way? document.write is evil, end of discussion.

Try with this:

var load_script = function(options) {
  options.owner_document = options.owner_document || document;

  var script_tag = options.owner_document.createElement('script');
  script_tag.setAttribute('type', 'text/javascript');
  script_tag.setAttribute('src', options.src);
  script_tag.onload = function() {
    script_tag.onreadystatechange = null;
    options.callback && options.callback();
  };
  script_tag.onreadystatechange = function() {
    if (script_tag.readyState == 'loaded' || script_tag.readyState == 'complete') {
      script_tag.onload = null;
      options.callback && options.callback();
    }
  };
  options.owner_document.getElementsByTagName('head')[0].appendChild(script_tag);
};

as you see, there's a simple API on that snippet:
src - source of the script
owner_document - document where the script will be inserted, defaults to the current document where the script is running from
callback - function to run after the script has loaded, anything that requires the src script is safe to be run inside this closure.

example usage:

// sample loading of jQuery
load_script({
  src: '/js/jquery-1.4.2.min.js',
  callback: function() {
    // jQuery is available at this point, run your code.

  }
});

alternatively, you can use loaders like requiere.js and LABjs

Upvotes: 8

user463535
user463535

Reputation:

You could write a recursive function that waits for the jquery library to load and then executes any code once the library is loaded. You probably want to add a conditional that breaks out of the recursion if it gets too deep.

 document.write("<html><head><script src='/js/jquery-1.4.2.min.js' type='text/javascript'></scr"+ "ipt><script type='text/javascript'>var wait_for_jQuery = function() {if (typeof $ === 'undefined') {setTimeout('wait_for_jQuery()', 1000);} else {alert($"+"().jquery);}};  wait_for_jQuery(); </scri" + "pt></head></html>");

Working example here: http://www.jsfiddle.net/YqTgM/36/

Upvotes: 0

Daniel Knoodle
Daniel Knoodle

Reputation: 384

Inside the <script></script> tag wrap your code in a document ready function so the libraries are loaded before running.

 $(document).ready(function() {
   // put all your jQuery code here
 });

Upvotes: -2

Related Questions