views:

71

answers:

2

I'm trying to lazy load javascripts, but I can't get it to work reliably. My pages load quite quickly and I want to keep it that way, so I'm not about to use a timeout to delay the loading. Besides document.readyState, how do I ensure the DOM is genuinely ready for modification?

Method I:

  1. poll readyState

  2. createElement script

  3. src = url

  4. appendElement to head

Results:

IE8: always aborts

FF3: loads first time, aborts every other

Chrome: loads first time, aborts every other

Method II: (lazyload included in head tag)

  1. load with lazyload

Results:

IE8: always aborts

FF3: works

Chrome: loads first time, aborts every other

+1  A: 

Javascript is hardly usable cross-browsers without a decent framework to help you span the differences. Probably most popular today is jquery, where, per this tutorial, you could use $(document).ready(). In dojo, also quite popular, you could use addOnLoad. And so on... and if you aren't using any framework, you're making life too hard for yourself: do yourself a favor and pick a JS framework you like!-)

Alex Martelli
"Hardly usable" is a bit strong.
Tim Down
@Tim, it's strong, but it fully reflects my feelings and experience: to get cross-browser JS to work properly, the only alternative -- doing your own user agent sniffing and browser bugs workarounds --overwhelms your application-oriented work, always misses some corner case or other, keeps hitting new browser releases with some fixes and some new bugs -- the use of "hell" in the Q's subject is actually quite a bit stronger than my "hardy" (some would object to it as swearing!-) but also perfectly appropriate and accurate (as is cursing, IMHO, when confronted with such a mess;-).
Alex Martelli
Thanks for your input Alex, but my problem is actually with the loading of frameworks!In the interests of server portability the idea is to load libraries based on dynamic information available at the client end. I realise I'm perhaps investing too much faith in satellite dependencies always existing etc... it's become one of those things I have to know one way or another; is it viable?It should be, and so I'm pursuing it! :-)
Ben
@Ben, for lazy AND fastest loading of popular JS frameworks, see http://code.google.com/apis/libraries/ and e.g. for an example of such lazily loading jquery see http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#tip1 .
Alex Martelli
I still need to load Google's library loader at runtime at the client's end.
Ben
@Ben, yep, and it's going to be _truly_ fast and lightweight: give it a try!
Alex Martelli
No no. I need to be able to load it dynamically. It has the same problem. Plus, even if it's written in to the HTML, it still doesn't work if I use it to load libraries immediately after the readyState is complete.
Ben
+2  A: 

If you put your <script> tag just above the </body> tag, you could do most things with DOM without it raising any errors, i.e. anything that is above the <script> tag is usually up for modification.

However, if you are looking for a more robust solution, you might have some progress by checking out how the major libraries are detecting if the DOM is ready, here's one for starters (jQuery): http://github.com/jquery/jquery/blob/master/src/core.js#L393

peol
or use the `window.onload` event.
Sarfraz
Yes, but the `window.onload` event waits to fire after all images (and other resources) has been downloaded as well, this is often not what you'd want since it would take longer than it needs to, and possibly decrease the user experience.
peol
I just can't get it to stick. Browsers, it seems, are reporting the DOM is ready just a tad sooner than it really is. `appendChild` too soon after the DOM is `ready` and it just overwrites the node I append. In IE8 for example, it overwrites the HEAD and loses the BODY altogether. I moderate timeout works. But then the question is how long is too long - and how long is not long enough? It looks like the feature I had in mind is going to have to be slated until something turns up...
Ben