2

I am developing a bookmarklet that requires a specific version of jQuery be loaded on the page. When I have to dynamically insert a jQuery script tag to meet the requirments of the bookmarklet I want to wait for the onload or onreadystatechange event on the script tag before executing any function that requires jQuery.

For some reason the onload and/or onreadystatechange events do not fire. Any ideas on what I am doing wrong here?

var tag = document.createElement("script");
tag.type = "text/javascript";
tag.src = "http://ajax.microsoft.com/ajax/jquery/jquery-" + version + ".min.js";
tag.onload = tag.onreadystatechange = function () {
    __log("info", "test");
    __log("info", this.readyState);
};
document.getElementsByTagName('head')[0].appendChild(tag);

The FULL code: http://gist.github.com/405215

5
  • The problem is that I am not seeing onreadystatechange being fired. The issue I am having is not related to jQuery. Commented May 18, 2010 at 16:56
  • @spoon16: ahh I misunderstoond. Works for me in FF (2), Chrome 4, IE6. Have you tried head.insertBefore(tag, head.firstChild) instead of appendChild? You may have markup on the outer page that is conflicting with this style of script inclusion. Or your browser may simply have the file cached? Commented May 18, 2010 at 17:04
  • On look of your __log function, this line will break: console[type].apply(null, consoleArgs). You need to pass the console object itself as the first argument to .apply(), otherwise nothing will get logged. Commented May 18, 2010 at 17:22
  • @Cresent Fresh your example is working for me, but I'm not at my dev machine right now so I can't debug my specific problem until I get home. You should put all this stuff into a proper answer so you can get credit. Commented May 18, 2010 at 18:20

3 Answers 3

2

Probably too late for you, but here's how I got round the problem.

Basically, it collects the "$(document).ready(function(){})" and "$(function(){})" calls and runs them after jQuery has finished loading.

Instead of using onLoad, we use setInterval to wait for the variable jQuery to become a function after adding the script tag to <head>

var $_i, $_r = [];
var $ = function(func){
   if(typeof(func) == 'function'){ $_r.push(func); }
   return{ ready: function(func){ $_r.push(func); } }
}
window.onload = function(){
   var s = document.createElement('script');
   s.setAttribute('type', 'text/javascript');
   s.setAttribute('src', 'https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js');
   document.getElementsByTagName("head")[0].appendChild(s);
   $_i = setInterval(function(){
      if(typeof(jQuery) == 'function'){
         clearInterval($_i);
         for(var i in $_r){
            $_r[i]();
         }
      }
   }, 100);
}
Sign up to request clarification or add additional context in comments.

Comments

1

if you use both events (tag.onload = tag.onreadystatechange), on IE9 it will be called two times.

Comments

0

You could always cheat, and put your onload/onreadystatechange logic into a setTimeout(), specifying a duration of 1 ms. Since you're inserting the script element into the DOM, you're guaranteed to see it execute before the timeout.

Example code:

var tag = document.createElement("script");
tag.type = "text/javascript";
tag.src = "http://ajax.microsoft.com/ajax/jquery/jquery-" + version + ".min.js";
document.getElementsByTagName('head')[0].appendChild(tag);
setTimeout(function(){
    __log("info", "test");
}, 1);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.