I am working on adding a widget to the client site, and I want to load js asynchronously so as not to block the loading of the client page. I read a lot of threads about this and tried to implement the sample proposed here, since my project is very similar:
http://friendlybit.com/js/lazy-loading-asyncronous-javascript
The problem is that the code in my dynamically loaded javascript file just doesn't execute. Sorry if this seems like a duplicate question, but I spent several hours searching and trying a few different methods, and I read a lot of posts, including these stackoverflow questions:
but I'm still trying my best to do this work, so I was hoping that if I ask a question, then someone here can help me!
Currently, I have received the following basic test; it’s obvious that a lot more is going on in my real script, but I just need to understand what is happening here (or, in fact, what is not happening).
So, in my code file "test.js" I just have:
run_test = function () { alert('hello from test'); };
then on the page I have:
(function () { load_test = function () { var t = document.getElementsByTagName('script')[0]; var s = document.createElement('script'); s.type = 'text/javscript'; s.async = true; s.src = 'test.js'; s.onload = s.readystatechange = function () { if (run_test) run_test(); s.onload = null; s.onreadystatechange = null; }; t.parentNode.insertBefore(s, t); }; load_test(); })();
I already tried several variations of this - I tried to remove "s.async = true" to make sure that it matters, but it doesn’t. Initially, I had instead of "load_test ();", as suggested in the first post I mentioned:
window.attachEvent ? window.attachEvent('onload', load_test) : window.addEventListener('load', load_test, false);
but the result is always the same, I never see the message "hello from the test." In fact, I can even put warnings in the load_test function - if I put a warning immediately before the line "s.onload = s.readystatechange .." I see this message, but the warning never appears inside this onload function. Thus, it seems that dynamically added script loading never fails.
BTW as an aside - it may or may not be relevant, but I usually test in Firefox, and if I look at the html in firebug, I see that the test.js script is loaded, but if I expand this node I just see the message "Restart page to get the source for ... ". It doesn’t matter how many times I reload the page, I don’t see the code. I tried testing in other browsers with the same results.
I cannot help but feel that I am missing something fundamental here; Any help would be greatly appreciated!
Pete
Thanks to everyone for input.
@zzzzBov, thanks, for example, although I’m not sure I fully understand, I thought that “onload” would fire once after the script was finished loading, just like binding the code to the onload event of the page. My understanding of "onreadystatechange" was that in IE it was easy to catch the same thing.
In response to your comments, a new script is inserted at the top of the page (using the insertBefore statement) immediately before the original script block (if the original script block is in the head, what is it).
As for the test.js path, I skipped the path just to simplify the example. My script path is definitely correct; I see through firebug that the script is actually added (to the head).
My problem was that after loading the script, it just did not start, but I think that I actually ran into some caching problems, since since then I have been working using the template described in the first link that I posted above ( here it is again for good measure: http://friendlybit.com/js/lazy-loading-asyncronous-javascript/ ).
So my code looks something like this:
(function () { var addscript = function () { var h = document.getElementsByTagName('head')[0], s = document.createElement('script'); s.type = "text/javascript"; s.async = true; s.src = "myscript.js"; h.appendChild(s); }; window.attachEvent ? window.attachEvent('onload', addscript) : window.addEventListener('load', addscript, false); })();
If you mark comments on this post, I think he explained why it is a good idea to still include "s.async = true", although in this case the script attaches to the onload event of the window.
My "real" main script really requires jQuery, so I think that in the end the solution will use something like this to load jQuery, and then, as soon as I find out what is loaded, let jQuery load any other scripts I need .
Thanks again for the help.
Pete