views:

393

answers:

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

A: 

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);
jimbojw
A: 

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);
}
DrKyoushu