window.onload 前でも DOM 処理が可能なら通知してくれる domready.js

window.onload 前でも DOM 処理が可能なら通知してくれる domready.js

2007/07/10 12:42pm

DOM 読み込み完了のタイミングで、任意の関数を実行できるようにする JavaScript ライブラリを書いてみた。

mootools の同様の機能を基にしていて、単体として使いやすいように外部ライブラリへの依存性をなくし、prototype.js とも併用できるようにしたもの。

現状、手元の環境では以下のブラウザで動作確認済み。

ただし、Mac IE では window.onload で代用するように実装してある。まあ、スクリプトエラーが出るよりマシだろう。

使い方

まず、domready.js を読み込む。

<script type="text/javascript" src="/javascripts/domready.js"></script>

prototype.js と併用する場合は prototype.js より後に読み込む。

<script type="text/javascript" src="/javascripts/prototype.js"></script>
<script type="text/javascript" src="/javascripts/domready.js"></script>

あとは、DOM 読み込み完了のタイミングで実行したい関数を Event.domReady.add で登録するだけ。

Event.domReady.add(function() {
  ...
});

他のイベントと登録方法が異なるのは直感的じゃない、とか言われそうだけど、正直あんまり気にならない。

経緯: window.onload の欠点

多くの Ajax 系実装では、ページ読み込み完了時に初期化などを実行するようになっている。

Event.observe(window, 'load', function() {
  ...
});

これは prototype.js によるイベント処理だが、window.onload イベントで処理を実行するために、関数を登録しているのが分かるだろう。

わざわざこんなことをしているのは、DOM を操作したいからだ。

だから、ほとんどの Ajax 系実装は window.onload イベントがやってくるのをじっと待っている。window.onload イベントのあとでは DOM ツリーは完全に構築されているし、他に DOM ツリーが構築済みなのを知る、適当なイベントもないからね。

もちろん、window.onload は完全じゃない … いや、それは嘘で、完全すぎる。DOM ツリーの構築を待つだけじゃなく、すべての画像の読み込みも待ってしまうんだ。そうすると、画像を多く含むようなページでは、Ajax の処理がいつまでたってもはじまらない、なんてことが起こって、これは、あんまり嬉しくない。

解決策: onDOMContentLoaded とクロスブラウザな実装

ブラウザごとにさまざまな解決策がある。

たとえば、Firefox など Mozilla 系のブラウザでは onDOMContentLoaded というイベントがあって、これはそのものずばり、DOM ツリーが読み込み完了したときに通知してくれるイベントだ。そして、Safari では document.readyState が、IE では defer 属性を有効にした script 要素の読み込みが利用できる(このへんの詳細は Dean Edwards: The window.onload Problem - Solved! に詳しい)。

また、mootools には window.addEvent('domready', ...)JQuery には同様に、$(document).ready() というクロスブラウザな実装が用意されている。嬉しいことに、prototype.js にも近いうちに同様の機能を取り込もう、という動きがあるようだ。

今回つくった domready.js は mootools の実装を基にしているが、だいたいどれも同じような実装みたいだ。