dean.edwards.name/weblog/2005/09/busted2/

window.onload – An Alternative Solution

As per Simon’s request here is an alternative version of yesterday’s window.onload solution.

This solution uses the ondocumentready event provided by DHTML Behaviors. The ondocumentready event fires when a behavior’s containing document has been completely parsed.

To enable this solution you must first attach the behavior file using CSS:

body {behavior: url(loaded.htc);}

The HTC file itself is ludicrously simple. We merely call our initialisation function from the attached event handler:

<component lightweight="true">
<attach event="ondocumentready" onevent="window.init()">
</component>

And that’s it.

Once again I’ve provided a sample page that demonstrates this technique.

Comments (36)

Leave a comment

One thing that I think was missed in the original discussion was that instead of replacing the onload this could be used in conjunction with it, and with a “normal” script block in the header to provide a rudimentary lifecycle for the page. There are certain behaviours that would fall nicely into each of these three places….. and then there is always unload as well. With the ability to register multiple behaviours to each of these it would aid in developers to be able to easily and reliably schedule for these lifecycle steps.

  • Comment by: Bryce
  • Posted:

[script type=”text/javascript”]

function init(){alert(“done”);}

[/script]

[style]

html{behavior:expression( void( this.complete = (document.readyState.toLowerCase()==”complete” || document.readyState.toLowerCase()==”interactive”) ) || void( (this.complete==true)?void(this.runtimeStyle.behavior=”none”)||void(window.init()):woid(0) ) )}

[/style]

  • Comment by: Hedger
  • Posted:

Hedger – I’ve said this many times before but onreadystatechange is not a reliable way to determine if the DOM has been loaded and parsed. Nice to see you using my expression hack though.;-)

  • Comment by: -dean
  • Posted:

Um….but HTC isn`t reliable for me since I often host many pages across dfferent domains.

Could you please explain that why onreadystatechange is not a reliable? I saw some of your demos beefore, but it seems to work well to me.

Thanks.

  • Comment by: Hedger
  • Posted:

Hedger – if HTCs can’t be used then use the original solution.

I don’t know why readyState is unreliable. The only thing I can say is that sometimes it works and sometimes it doesn’t. The complete state is the same as window.onload and the interactive state is usually OK for small pages but doesn’t always imply that the DOM is complete. This is especially true if you are using document.write to generate content.

  • Comment by: -dean
  • Posted:

I think that readyState is reliable but one must test two precise states like this.

if(/loaded|complete/.test(window.event.srcElement.readyState) DO THIS…

  • Comment by: rickman
  • Posted:

hi my names is emma and it great to read this all

  • Comment by: emma turner
  • Posted:

Disarm IE: My Dev Wishlist for Other Browsers

I’ve had bad experiences with HTCs. Specifically, once I load an HTC and apply that behavior to multiple elements, it takes a very long time to unload the page (i.e. going to another page or simply reloading). I’m not sure if this is just some system quirk, but I’m staying away from HTCs for now.

  • Comment by: Maian
  • Posted:

It really works like a charm. IE only fires an error (Object doesn’t support this property or method) when you try to print (preview) the document. Once you remove the (optional) lightWeight attribute or the enclosing component element the problem is gone. MSDN states false, the default value for the lightWeight attribute, is then used, but I can’t really see any change in performance. Perhaps you know what the real drawback of not using lightWeight="true" is?

Removing lightWeight=”true” did the trick for me:)

And thanks to Dean for pushing the limits of IE:)

Strange. lighweight="true" is supposed to mean that the behavior does not alter the DOM. This should result in faster loading behaviors. Not sure how this would affect print preview.

  • Comment by: -dean
  • Posted:

[…] who are too impatient to wait for window.onload to fire, I found some interesting info on this site about firing events when the DOM is finished loading but before all the images and stu […]

dear dean,

in one of my projects i have to use a lot of iframes with a special banner manager system. i tried out both of your solutions but to my greatest regret it seems that they don’t work with iframes. i provide you with two sample pages but they are very simple. i only changed the img tags to iframes in your original sample pages.

i found another post in this onload problem topic, and there is an iframe and that solution seems to work, but as far as i understand it uses the readyState which you have declared unreliable.

so my question is, where is my mistake if there is any or what can i do to solve this problem? (i know i shouldn’t use iframes… ;))

  • Comment by: Wiktor
  • Posted:

uhh, i forgot to mention – but unfortunately it’s obvious:(– that only internet explorer is problematic…

(i’ve just relalized that the working example is provided by hedger, who wrote the second comment… :))

  • Comment by: Wiktor
  • Posted:

I´ve heard htc via css is executed even when javascript is disabled. “window.init” would not exist in that case given an error, right? Maybe a better approach would be using javascript itself? Something like:

document.body.style.behavior=’expression(init())’

(and not mixing css and javascript…) That´s what I use to load my init functions on startup in IE. Great blog, thanks Dean.

  • Comment by: paulo
  • Posted:

You don’t have to use an external .htc file (with its problems). You can use : body {behavior:expression(init());} in your stylesheet or you can even do it entirely in javascript (better: no css for methods) by adding var styleSheetFromScript = false; function addStyle(selector,properties){

} }

addCSSRule(‘body’,’behavior:expression(init());’);

to the code. AddCSSRule is a function which adds CSS rule from javascript (I can’t post it here because the xhtml-strict validator in this blog won’t let me).

grtz, Mark D.

oops

var styleSheetFromScript = false; function addStyle(selector,properties){

} } was posted by coincidence

sorry

Just to correct comments 16/17/18, adding init to a behaviour in the CSS doesn’t work as the init method will execute before the DOM is full loaded. Dean’s method still stands.

Using your example to display a popup message onload. With firefox, the popup message continously loads. Why is this?

  • Comment by: ericmac
  • Posted:

@ericmac – No sample code, no answer.

  • Comment by: -dean
  • Posted:

[…] و http://dean.edwards.name/weblog/2005/09/busted2/ […]

I have implemented a dynamic homepage where I needed to update a field with a default value loaded from an external file; the onload command would simply be an ideal solution.

However, even though onload worked as it should (or as I expected it to work) on Mozilla and Opera, it did not work with MSIE. After searching the web for solutions, I found this great site where different solutions have been discussed in detail. Unfortunately, though, it did not work on my site…

However, afer some trial and error I jumped into a simple solution which seems to work perfectly on all browsers (to be precise, I have only tested it on Mozilla, Opeara and IE). The solution is simply to add the function call immediately after your [/BODY] tag.

i.e.

[HTML]

[HEAD]

… something here …

[/HEAD]

[BODY]

… (hopefully) something meaningful here …

[/BODY]

[script language=JavaScript] foo(); [/script]

[/HTML]

For the complete implementation, please visit my homepage provided in the hyperlink below…

[…] و http://dean.edwards.name/weblog/2005/09/busted2 و لأنه أمر مهم أحببت وضعه … […]

Hedger – you can embed HTC :

body {behavior: url(javascript:”<component lightweight=’true’><attach event=’ondocumentready’ onevent=’window.init()’></component>”);}

  • Comment by: LungZeno
  • Posted:

@LungZeno – How about testing the code you post here? Your sample code does not work at all.

  • Comment by: -dean
  • Posted:

[…] Referência: http://dean.edwards.name/weblog/2005/09/busted2/ […]

[…] و http://dean.edwards.name/weblog/2005/09/busted2 و لأنه أمر مهم أحببت وضعه … […]

+1

  • Comment by: bobby
  • Posted:

Has anyone actually tried the code posted by Hedger?
I have serious doubts that the function call woid(0) is going to work…

[…] Inspiration and information to this solution has been taken from the following sources: Dean Edward’s blog (window.onload Problem – Solved!, follow up and window.onload – An Alternative Solution) and Diego Perini’s site (ContentLoaded Test Case). MSDN was also useful on background information relating to HTC and behavior. […]

I’m experiencing a strange issue in Internet Explorer 7 – document.readyState returns “interactive” after window.onload fires. Has anyone come across this behavior before?

  • Comment by: DV
  • Posted:

[…] HTC Behavior by Dean Edwards […]

i’ve tried both the original and alternative solution and found that (on IE6) both fire after the html text is already rendered – is it possible to catch it earlier – after dom load but before any render?

  • Comment by: Paul Arzul
  • Posted:

the original solution (comments closed) suggested:

/*@cc_on @*/
/*@if (@_win32)
document.write("<script defer src=ie_onload.js><\/script>");
/*@end @/

that seems to create a nested comment. why not close it? or perhaps:

//@if (@_win32) document.write("<script defer src=ie_onload.js><\/script>");
  • Comment by: Paul Arzul
  • Posted:

[…] […]

Comments are closed.