domready.mustache revision e9b01de77b1a53553e58caf4f0c5392735102fc1
8e2f5a54575e4da16c524b6c45cba19a4ad00070Nicholas C. Zakas<div class="intro">
8e2f5a54575e4da16c524b6c45cba19a4ad00070Nicholas C. Zakas <p>The `event-base` module includes three special events that can be used to execute code as soon as the DOM, or certain elements in the DOM tree, are ready to be scripted.</p>
8e2f5a54575e4da16c524b6c45cba19a4ad00070Nicholas C. Zakas
b33d3bf66f037e3c87d1b857d3706eee0072e0cdNicholas <p>Because all of these events are designed to target elements that aren't present or parsed yet, <strong>you must use `Y.on(...)` to subscribe to them</strong>. `Y.one('#notHereYet')` will return `null`, and you can't do much with `null`.</p>
3311c55c55c920279703d40fac28a11fe9d8494cNicholas
0b5e1d37b52292808888e5c0674f90c2bbc3c210Nicholas <p>Be sure to read <a href="#caveat">the final note on this page</a> about performance.</p>
9062ea13d64c4cc70df35e5e10a77e55f2029d41Nicholas</div>
9062ea13d64c4cc70df35e5e10a77e55f2029d41Nicholas
3311c55c55c920279703d40fac28a11fe9d8494cNicholas<h2 id="domready">`domready`</h2>
a2def8478a773d7a61b1d17ab98383371861d7baNicholas
300ddd61d98200ad4f5bfe82c94ba0a802349bdaNicholas```
a2def8478a773d7a61b1d17ab98383371861d7baNicholas<!doctype html>
359c147bb7d734b478b47d664e9f09e5f2f47cf1Nicholas<html>
359c147bb7d734b478b47d664e9f09e5f2f47cf1Nicholas<head>
359c147bb7d734b478b47d664e9f09e5f2f47cf1Nicholas <meta charset="utf-8">
52573a9e39b00926b9b978f85340102df4b4063dNicholas <title>domready</title>
52573a9e39b00926b9b978f85340102df4b4063dNicholas <script src="...yui-min.js"></script>
52573a9e39b00926b9b978f85340102df4b4063dNicholas <script>
52573a9e39b00926b9b978f85340102df4b4063dNicholas YUI().use('event-base', function (Y) {
52573a9e39b00926b9b978f85340102df4b4063dNicholas var notHereYet = Y.one('#readygo'); // null
0b5e1d37b52292808888e5c0674f90c2bbc3c210Nicholas
cd4f0c50c6a7faa3fd8e38236929bb9b37bc11b7Nicholas C. Zakas Y.on('domready', function () {
b5983d53e5f50f3137991a80821078a32a4be3b3Nicholas C. Zakas Y.one('#readygo').on('click', function () {
b044439bdcfcb383ec0e2f5db45fea4acea4fb9cNicholas C. Zakas Y.log('This works fine, before the images are loaded');
b5983d53e5f50f3137991a80821078a32a4be3b3Nicholas C. Zakas });
3b582a24e4eec5a8ccf9dce2c722ee81023e6dbaNicholas C. Zakas });
cd4f0c50c6a7faa3fd8e38236929bb9b37bc11b7Nicholas C. Zakas });
8e2f5a54575e4da16c524b6c45cba19a4ad00070Nicholas C. Zakas </script>
b33d3bf66f037e3c87d1b857d3706eee0072e0cdNicholas</head>
8e2f5a54575e4da16c524b6c45cba19a4ad00070Nicholas C. Zakas<body>
8e2f5a54575e4da16c524b6c45cba19a4ad00070Nicholas C. Zakas ... lots of markup including images and stuff
8e2f5a54575e4da16c524b6c45cba19a4ad00070Nicholas C. Zakas <button id="readygo">Go!</button>
8e2f5a54575e4da16c524b6c45cba19a4ad00070Nicholas C. Zakas</body>
8e2f5a54575e4da16c524b6c45cba19a4ad00070Nicholas C. Zakas</html>
7a2fdaed1646e4131f96888dce8170e96e79a5b4Nicholas C. Zakas```
7a2fdaed1646e4131f96888dce8170e96e79a5b4Nicholas C. Zakas
7a2fdaed1646e4131f96888dce8170e96e79a5b4Nicholas C. Zakas<p>Modern browsers support an event that signals when the markup has been
7a2fdaed1646e4131f96888dce8170e96e79a5b4Nicholas C. Zakascompletely parsed and the DOM tree is built. This event happens before the
7a2fdaed1646e4131f96888dce8170e96e79a5b4Nicholas C. Zakaswindow's `load` event, which fires when all images and other resources have
6eccb99d95a457b8714d60222b7bbc2ebaa0c1f2Nicholas C. Zakasbeen fetched. For setting up event subscriptions and core page interactivity,
6eccb99d95a457b8714d60222b7bbc2ebaa0c1f2Nicholas C. Zakasit's usually enough that all DOM elements are available, regardless of their
a8240e5d8edb13039000a849e3b9ba2e50d93c55Nicholas C. Zakasloading state.</p>
f28a71a935fd9c3a101c8f45f192a7996c62ef2fNicholas C. Zakas
7a2fdaed1646e4131f96888dce8170e96e79a5b4Nicholas C. Zakas<p>The `domready` event abstracts over the patchwork necessary for browsers without a native "domready" event.</p>
8e2f5a54575e4da16c524b6c45cba19a4ad00070Nicholas C. Zakas
b33d3bf66f037e3c87d1b857d3706eee0072e0cdNicholas<p>Note the subscription signature does not include a target, only the event name and callback.</p>
8e2f5a54575e4da16c524b6c45cba19a4ad00070Nicholas C. Zakas
8e2f5a54575e4da16c524b6c45cba19a4ad00070Nicholas C. Zakas<h2 id="contentready">`contentready`</h2>
8e2f5a54575e4da16c524b6c45cba19a4ad00070Nicholas C. Zakas
```
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>contentready</title>
<script src="...yui-min.js"></script>
<script>
YUI().use('event-base', function (Y) {
var notHereYet = Y.one('#list'); // null
function addItem() {
// children of #todo are in the DOM tree
this.one('ul').append('<li>This will be four</li>');
}
Y.on('contentready', addItem, '#todo');
});
</script>
</head>
<body>
... lots of markup including images and stuff
<div id="todos">
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</div>
... more markup
</body>
</html>
```
<p>You may want to script some nodes that are in the middle of the page markup inside a specific containing element. You just need to know that the container and its children have been parsed from markup and added to the DOM tree. But you don't want to wait for the entire DOM tree to finish. That's what the `contentready` event is for.</p>
<p>YUI will check the DOM periodically, looking for an element matching the selector passed as the the third argument. When it finds one and can verify that that element's children are also in the DOM tree, it will execute the callback.</p>
<p>Callbacks will be executed with `this` assigned to the Node matching the selector.</p>
<h2 id="available">`available`</h2>
```
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>available</title>
<script src="...yui-min.js"></script>
<script>
YUI().use('event-hover', function (Y) {
var notHereYet = Y.one('#highlight-me'); // null
function over() {
this.addClass("over");
}
function out() {
this.removeClass("over");
}
function addSubscribers() {
this.on('hover', over, out);
}
Y.on('available', addSubscribers, '#highlight-me');
});
</script>
</head>
<body>
... lots of markup including images and stuff
<div id="highlight-me">
... stuff that doesn't need to be ready
</div>
... more markup
</body>
</html>
```
<p>The `available` event is almost identical to <a href="#contentready">`contentready`</a> except it does not wait for children of the matching element to be ready. If your code only needs to reference the targeted Node, not any of its children, use `available` instead of `contentready`.</p>
<h2 id="caveat">Just put your &lt;script&gt; tags at the bottom</h2>
<p>You might not need to use any of these events, and maybe you shouldn't.</p>
<p>It is always safe to script nodes defined in the markup above the JavaScript that references it. In practice, if you have the option, it is preferable to move &lt;script&gt; tags below the markup that it needs in place, and often it is best to simply <a href="http://developer.yahoo.com/blogs/ydn/posts/2007/07/high_performanc_5/">move scripts to the bottom of the page</a>.</p>
```
<div id="stuff-i-need">
...
</div>
<script>
// Scripts below markup can access the DOM elements above
YUI().use('node', function (Y) {
Y.one('#stuff-i-need', function () {
Y.log('This will always work');
});
});
</script>
```