YUI 3.x Home -

YUI Library Examples: Event: Using 'available', 'contentready', and 'domready'

Event: Using 'available', 'contentready', and 'domready'

As web pages get richer, they tend to get slower. One way to make your pages as responsive as possible is to carefully storyboard the page-load and page-paint processes so that the interactions most central to the page's purpose are enabled as early as possible. The window object's load event won't happen until the full DOM and all image data have loaded. Putting off script execution until after the page loads can be optimal for some scripts, but sometimes you won't want to wait that long to begin interacting with the page via script.

The Event Utility gives you three additional interesting moments that occur during a page's load process:

  1. available: available targets a single element and fires when that element is available (when it responds to document.getElementById()) — but you can't count on the element's children having been loaded at this point.
  2. contentready: When you care about not just your target element but its children as well, use contentready. This event will tell you that your target element and all of its children are present in the DOM.
  3. domready: Some DOM scripting operations cannot be performed safely until the page's entire DOM has loaded. The domready event will let you know that the DOM is fully loaded and ready for you to modify via script. This custom event takes the place of the onDOMReady event from previous versions of YUI.

In the example box below, available, contentready and domready are all in use. A <div> (with a green background) loads; it has 100 chidren; one of those children is an arbitrarily large image that will take awhile to load. Keep an eye on the console, if you have one available in your browser. You'll see that the <div> (1) becomes available, (2) its content becomes ready (after all of its 100 children have loaded), (3) the DOM becomes ready, and finally (4) the page loads.

Internet Explorer note: It isn't always safe to modify content during the available/contentready until after the domready moment. In this browser, domready will execute before the available/contentready listeners.

3.x note: This example has all of the YUI requirements included on the page. This differs from the default YUI configuration, which will dynamically load required YUI modules. Dynamic loading works asynchronously, so the domready moment likely will have passed when it comes time to bind the listeners, and possibly the window load event as well. All of the event listeners will actually fire in this case, but the order of the events will not be the same. domready will execute before the available/contentready listeners, and the window load event may as well.

  • child node #0
  • child node #1
  • child node #2
  • child node #3
  • child node #4
  • child node #5
  • child node #6
  • child node #7
  • child node #8
  • child node #9
  • child node #10
  • child node #11
  • child node #12
  • child node #13
  • child node #14
  • child node #15
  • child node #16
  • child node #17
  • child node #18
  • child node #19
  • child node #20
  • child node #21
  • child node #22
  • child node #23
  • child node #24
  • child node #25
  • child node #26
  • child node #27
  • child node #28
  • child node #29
  • child node #30
  • child node #31
  • child node #32
  • child node #33
  • child node #34
  • child node #35
  • child node #36
  • child node #37
  • child node #38
  • child node #39
  • child node #40
  • child node #41
  • child node #42
  • child node #43
  • child node #44
  • child node #45
  • child node #46
  • child node #47
  • child node #48
  • child node #49
  • child node #50
  • child node #51
  • child node #52
  • child node #53
  • child node #54
  • child node #55
  • child node #56
  • child node #57
  • child node #58
  • child node #59
  • child node #60
  • child node #61
  • child node #62
  • child node #63
  • child node #64
  • child node #65
  • child node #66
  • child node #67
  • child node #68
  • child node #69
  • child node #70
  • child node #71
  • child node #72
  • child node #73
  • child node #74
  • child node #75
  • child node #76
  • child node #77
  • child node #78
  • child node #79
  • child node #80
  • child node #81
  • child node #82
  • child node #83
  • child node #84
  • child node #85
  • child node #86
  • child node #87
  • child node #88
  • child node #89
  • child node #90
  • child node #91
  • child node #92
  • child node #93
  • child node #94
  • child node #95
  • child node #96
  • child node #97
  • child node #98
  • child node #99
Uluru

Source Code for This Example:

Markup:

The markup used to create the DOM is very simple, consisting of a <div> that holds a <ul> with 100 child <li>s and a single ~3MB image. The <ul> will take a little time to load, and the image (loading over the internet) will take a few seconds to load even on a fast connection. That should allow us to see in the Logger console some time deltas between when the <div> whose ID is contentContainer becomes available, when its children (those 100 <li>s) are ready, when the DOM is ready (including all the navigation elements on the page), and lastly when the page loads (ie, when that ~3MB image is fully loaded).

  1. <div id="contentContainer">
  2.  
  3. <!--a ul with an arbitrarily large number of children:-->
  4. <ul>
  5. <li>...</li>
  6. <!--...100 more of these-->
  7. </ul>
  8.  
  9. <img src="http://developer.yahoo.com/yui/docs/assets/examples/exampleimages/large/uluru.jpg" width="500" alt="Uluru" id="image" />
  10.  
  11. </div>
<div id="contentContainer">
 
    <!--a ul with an arbitrarily large number of children:-->
    <ul>
        <li>...</li>
        <!--...100 more of these-->
    </ul>
 
    <img src="http://developer.yahoo.com/yui/docs/assets/examples/exampleimages/large/uluru.jpg" width="500" alt="Uluru" id="image" />
 
</div>

CSS:

The CSS colors the contentContainer element and hides the big list to keep the example more compact.

  1. <style type="text/css">
  2. #contentContainer {padding:1em; background:#999966;}
  3. #contentContainer ul {height:0px; overflow:hidden;}
  4. </style>
<style type="text/css">
    #contentContainer {padding:1em; background:#999966;}
    #contentContainer ul {height:0px; overflow:hidden;}
</style>

JavaScript:

In the script, we create an anonymous function that contains our YUI instance (Y). We then subscribe to the four events in which we're interested and, in each case, log a message to the console or Logger to express the timing of the events as they fire.

  1. YUI().use('*', function(Y) {
  2. var results = Y.one('#demo');
  3.  
  4. //we'll use this handler for all of our callbacks; the
  5. //message being logged will always be the last argument.
  6. function fnHandler(e) {
  7. var message = arguments[arguments.length - 1];
  8. // Y.log(message, "info", "example");
  9. results.set('innerHTML', results.get('innerHTML') + '<p>' + message + '</p>');
  10. }
  11.  
  12. //assign page load handler:
  13. Y.on("load", fnHandler, window, Y, "The window load event fired. The page and all of its image data, including the large image of Uluru, has completed loading.");
  14.  
  15. //assign domready handler:
  16. Y.on("domready", fnHandler, Y, "The DOMContentLoaded event fired. The DOM is now safe to modify via script.");
  17.  
  18. //assign 'contentready' handler:
  19. Y.on("contentready", fnHandler, "#contentContainer", Y, "The 'contentready' event fired for the element 'contentContainer'. That element and all of its children are present in the DOM.");
  20.  
  21. //assign 'available' handler:
  22. Y.on("available", fnHandler, "#contentContainer", Y, "The 'available' event fired on the element 'contentContainer'. That element is present in the DOM.");
  23.  
  24. fnHandler("", "As the page loads, you'll see the 'available', 'contentready', 'domready', and window load events logged here as they fire in sequence.");
  25. });
YUI().use('*', function(Y) {
    var results = Y.one('#demo');
 
    //we'll use this handler for all of our callbacks; the
    //message being logged will always be the last argument.
    function fnHandler(e) {
        var message = arguments[arguments.length - 1];
        // Y.log(message, "info", "example");
        results.set('innerHTML', results.get('innerHTML') + '<p>' + message + '</p>');
    }
 
    //assign page load handler:
    Y.on("load", fnHandler, window, Y, "The window load event fired.  The page and all of its image data, including the large image of Uluru, has completed loading.");
 
    //assign domready handler:
    Y.on("domready", fnHandler, Y, "The DOMContentLoaded event fired.  The DOM is now safe to modify via script.");
 
    //assign 'contentready' handler:
    Y.on("contentready", fnHandler, "#contentContainer", Y, "The 'contentready' event fired for the element 'contentContainer'.  That element and all of its children are present in the DOM.");
 
    //assign 'available' handler:
    Y.on("available", fnHandler, "#contentContainer", Y, "The 'available' event fired on the element 'contentContainer'.  That element is present in the DOM.");
 
    fnHandler("", "As the page loads, you'll see the 'available', 'contentready', 'domready', and window load events logged here as they fire in sequence.");
});

Copyright © 2009 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings