JavaScript onload / onreadystatechange not firing when dynamically adding script tag to page

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

For some reason the onload and / or onreadystatechange events are not firing. 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);

      

FULL Code: http://gist.github.com/405215

+2


a source to share


3 answers


It might be too late for you, but here's how I got around the problem.

Basically, it collects "$ (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 jQuery variable to become a function after adding the script tag to the <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);
}

      

+2


a source


if you use both events (tag.onload = tag.onreadystatechange), in IE9 it will be called twice.



+1


a source


You can always cheat and put your onload / onreadystatechange logic in setTimeout () by specifying a duration of 1ms. Since you are inserting a script element into the DOM, you are guaranteed to see it execute before it times out.

Sample 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);

      

0


a source







All Articles