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

Advertisement

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

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

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

  • IE 7 (XP standalone)
  • IE 6 SP2
  • Firefox 2.0.0.4
  • Opera 9.21
  • Safari 2.0.4
  • Mac Firefox 2.0.0.4
  • Mac IE 5.2.3

ただし、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 の実装を基にしているが、だいたいどれも同じような実装みたいだ。

Leave a Reply

2 Comments

juce6ox

IE/DOMLoad : behavior expression

IEの独自実装による document.write を使わない DOMロード の検知方法を考えました。
CSSのbehaviorとexpressionを使います。
... document.documentElement.style.setExpression('behavior', 'document.documentElement.polli...

AUSGANG SOFT

DOMContentLoadedとGreasemonkey

今ごろ、まるごとJavaScript &amp; Ajax ! Vol.1を読ん...

Want fries with that?

Open Source Projects