f



window.onload when DOM complete

There has been a bit of work done to get an init() function to run when 
the DOM is complete but before all the images have been downloaded.  The 
idea is to kickoff init() scripts when all the elements are there but 
not wait for large images.

Below is a script which uses 3 different techniques, one each for IE, 
Safari and Mozill/Opera 9.  The Safari version uses browser sniffing, 
but I think with a little work that could be removed - the following 
code is really just a proof of concept.

My simple solution is to insert a script element that calls the init 
function just before the closing body tag.  It seems just as good to me, 
always runs before the above methods, is far less code and likely to run 
more consistently in more browsers.  What do others think?


Script:

<title>Onload</title>
<script type="text/javascript">
   function init(s){
     if (!this.init.called) {
       this.init.called = true;
       document.getElementById('xx').innerHTML += s;
     }
   }
   init.called = false;

   /* for Internet Explorer (using conditional comments)
    * From Matthias Miller:
    * 
http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
    */
   /*@cc_on @*/
   /*@if (@_win32)
   document.write("<script id=__ie_onload defer "
     + "src=javascript:void(0)><\/script>");
   var script = document.getElementById("__ie_onload");
   script.onreadystatechange = function() {
     if (this.readyState == "complete") {
       init('IE version'); // call the onload handler
     }
   };
   /*@end @*/

   /* for Mozilla and Opera 9 browsers
    * From Dean Edwards:
    * http://dean.edwards.name/weblog/2005/09/busted/
    */
   if (document.addEventListener) {
     document.addEventListener(
       "DOMContentLoaded",
       function(){init('Mozilla & Opera 9 version');},
       false
     );
   }

   /* Safari/Webkit version
    * From John Resig (author of jQuery)
    */
   if (/WebKit/i.test(navigator.userAgent)) { // sniff
     var _timer = setInterval(function() {
       if (/loaded|complete/.test(document.readyState)) {
         clearInterval(_timer);
         init('Safari/Webkt version'); // call the onload handler
       }
     }, 10);
   }
</script>

<body>
   <div id="xx"></div>
   <img src="http://www.space.com/images/ig320_mcnaught_Boomer_02.jpg">

   <!-- If uncommented, the following script runs before the others -->

   <script type="text/javascript">
   //   init('Footer script used');
   </script></body>


-- 
Rob
0
RobG
2/9/2007 1:46:16 PM
comp.lang.javascript 38370 articles. 2 followers. javascript4 (1315) is leader. Post Follow

2 Replies
9769 Views

Similar Articles

[PageSpeed] 41

On Feb 9, 5:46 am, RobG <r...@iinet.net.au> wrote:
> There has been a bit of work done to get an init() function to run when
> the DOM is complete but before all the images have been downloaded.  The
> idea is to kickoff init() scripts when all the elements are there but
> not wait for large images.
>
> Below is a script which uses 3 different techniques, one each for IE,
> Safari and Mozill/Opera 9.  The Safari version uses browser sniffing,
> but I think with a little work that could be removed - the following
> code is really just a proof of concept.
>
> My simple solution is to insert a script element that calls the init
> function just before the closing body tag.  It seems just as good to me,
> always runs before the above methods, is far less code and likely to run
> more consistently in more browsers.  What do others think?
>
> Script:
>
> <title>Onload</title>
> <script type="text/javascript">
>    function init(s){
>      if (!this.init.called) {
>        this.init.called = true;
>        document.getElementById('xx').innerHTML += s;
>      }
>    }
>    init.called = false;
>
>    /* for Internet Explorer (using conditional comments)
>     * From Matthias Miller:
>     *http://www.outofhanwell.com/blog/index.php?title=the_window_onload_pr...
>     */
>    /*@cc_on @*/
>    /*@if (@_win32)
>    document.write("<script id=__ie_onload defer "
>      + "src=javascript:void(0)><\/script>");
>    var script = document.getElementById("__ie_onload");
>    script.onreadystatechange = function() {
>      if (this.readyState == "complete") {
>        init('IE version'); // call the onload handler
>      }
>    };
>    /*@end @*/
>
>    /* for Mozilla and Opera 9 browsers
>     * From Dean Edwards:
>     *http://dean.edwards.name/weblog/2005/09/busted/
>     */
>    if (document.addEventListener) {
>      document.addEventListener(
>        "DOMContentLoaded",
>        function(){init('Mozilla & Opera 9 version');},
>        false
>      );
>    }
>
>    /* Safari/Webkit version
>     * From John Resig (author of jQuery)
>     */
>    if (/WebKit/i.test(navigator.userAgent)) { // sniff
>      var _timer = setInterval(function() {
>        if (/loaded|complete/.test(document.readyState)) {
>          clearInterval(_timer);
>          init('Safari/Webkt version'); // call the onload handler
>        }
>      }, 10);
>    }
> </script>
>
> <body>
>    <div id="xx"></div>
>    <img src="http://www.space.com/images/ig320_mcnaught_Boomer_02.jpg">
>
>    <!-- If uncommented, the following script runs before the others -->
>
>    <script type="text/javascript">
>    //   init('Footer script used');
>    </script></body>
>
> --
> Rob

That's the easy way to do it, to be sure - just put the onload code in
the bottom of the HTML, and you're guaranteed to start as soon as the
DOM is finished parsing but not before.  The only real drawback I see
to this is coding style and the dream of unobtrusive scripting:  when
working on a project with several other developers, I like to keep all
my JS in JS files separate from all HTML, so all my JS code is in one
place, which really helps for managing more complex projects.  But
that's more of a personal preference, I guess, and if all you've got
is a simple function call at the end of your document it's not even
that big of a problem.  In fact, I see Google using this technique a
lot, so there's clearly established, respectable product code out
there doing this.  If it works for you, go for it.

-David

0
David
2/10/2007 5:17:26 AM
On Feb 9, 5:46 am, RobG <r...@iinet.net.au> wrote:
> There has been a bit of work done to get an init() function to run when
> the DOM is complete but before all the images have been downloaded.  The
> idea is to kickoff init() scripts when all the elements are there but
> not wait for large images.
>
> Below is a script which uses 3 different techniques, one each for IE,
> Safari and Mozill/Opera 9.  The Safari version uses browser sniffing,
> but I think with a little work that could be removed - the following
> code is really just a proof of concept.
>
> My simple solution is to insert a script element that calls the init
> function just before the closing body tag.  It seems just as good to me,
> always runs before the above methods, is far less code and likely to run
> more consistently in more browsers.  What do others think?

I've been thinking about this in quite a bit of detail very recently
and wrote a blog article that has some great responses that you might
like to read.

"The window.onload problem (still)"
<URL: http://peter.michaux.ca/article/553>

Peter

0
Peter
2/10/2007 6:31:11 AM
Reply: