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
Comment: #1
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: #2
[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: #3
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 myexpression
hack though.Comment: #4
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: #5
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. Thecomplete
state is the same aswindow.onload
and theinteractive
state is usually OK for small pages but doesn’t always imply that the DOM is complete. This is especially true if you are usingdocument.write
to generate content.Comment: #6
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: #7
hi my names is emma and it great to read this all
Comment: #8
Disarm IE: My Dev Wishlist for Other Browsers
Comment: #9
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: #10
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 enclosingcomponent
element the problem is gone. MSDN statesfalse
, the default value for thelightWeight
attribute, is then used, but I can’t really see any change in performance. Perhaps you know what the real drawback of not usinglightWeight="true"
is?Comment: #11
Removing lightWeight=”true” did the trick for me
And thanks to Dean for pushing the limits of IE
Comment: #12
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: #13
[…] 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 […]
Comment: #14
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: #15
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: #16
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: #17
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 addingvar 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.
Comment: #18
oops
var styleSheetFromScript = false; function addStyle(selector,properties){
} } was posted by coincidence
sorry
Comment: #19
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.
Comment: #20
Using your example to display a popup message onload. With firefox, the popup message continously loads. Why is this?
Comment: #21
@ericmac – No sample code, no answer.
Comment: #22
[…] و http://dean.edwards.name/weblog/2005/09/busted2/ […]
Comment: #23
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…
Comment: #24
[…] و http://dean.edwards.name/weblog/2005/09/busted2 و لأنه أمر مهم أحببت وضعه … […]
Comment: #25
Hedger – you can embed HTC :
body {behavior: url(javascript:”<component lightweight=’true’><attach event=’ondocumentready’ onevent=’window.init()’></component>”);}
Comment: #26
@LungZeno – How about testing the code you post here? Your sample code does not work at all.
Comment: #27
[…] Referência: http://dean.edwards.name/weblog/2005/09/busted2/ […]
Comment: #28
[…] و http://dean.edwards.name/weblog/2005/09/busted2 و لأنه أمر مهم أحببت وضعه … […]
Comment: #29
+1
Comment: #30
Has anyone actually tried the code posted by Hedger?
I have serious doubts that the function call
woid(0)
is going to work…Comment: #31
[…] 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. […]
Comment: #32
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: #33
[…] HTC Behavior by Dean Edwards […]
Comment: #34
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: #35
the original solution (comments closed) suggested:
that seems to create a nested comment. why not close it? or perhaps:
Comment: #36
[…] […]
Comments are closed.