DOM のロード直後に実行する関数の指定方法
Javascript で DOM を操作する際にはページ内の DOM 要素がロードされている必要がある。
このとき問題になるのは、
- DOM がロードされたタイミングをどのように検知するか。
- DOM がロードされたタイミングで実行する関数の指定方法。
まず、次のような html を考える。
<html>
<head>
<title></title>
<script>
// ページヘッダの読み込み時刻を記録
var start = new Date();
</script>
</head>
<body>
<!--ロードに10秒かかる画像を指定-->
<img src="http://example.com/sleep10" />
</body>
</html>
ここで、 image 要素には 10 秒後に結果を返すスクリプトを指定している。
window.onload を使い、ページのヘッダが読み込まれてから、関数が実行されるまでの実行時間を計測し、Firebug コンソールに書き込む。
window.onload = function(){
// 関数が実行され始める時刻を記録
stop = new Date();
// firebug のコンソールにログ出力
console.log('window.onload' + (stop - start));
}
/////window.onload 100005
window.onload で指定した関数はページ内の画像ファイルが全てロードされてから実行されるので、結果は、以下のようになる。
画像のロード時間 (10秒) + 関数の実行時間
しかし、DOM を操作するために、画像が完全にロードされている必要はない。
そこで、以下のように、body の最後の子要素に、実行したい関数を書き、DOM がロードされたら自動的に関数が実行されるようにする。
この方法だと、DOM がロードされているが、画像のロードを待たずにすむので、先程より速くなる。
<html>ただし、この方法は html 内に余計なDOM 要素を加えるので一般的に推奨されていない。
<head>
<title></title>
<script>
var start = new Date();
</script>
</head>
<body>
<!--ロードに10秒かかる画像を指定-->
<img src="http://example.com/sleep10" />
<!--この位置では全ての DOM 要素は読み込まれている-->
<script>
stop = new Date();
console.log('script-end ' + (stop - start));
</script>
</body>
</html>
/////script-end 5
jQuery では、以下のように function 部分に任意の関数を指定すると、
$(document).ready(function(){});
DOM 要素がロードされてから、実行される関数を指定可能である。ロード後に実行したい関数を指定できる数に制限はなく、DOM ロード後に実行したい関数が複数ある場合は、
// DOM ロード後に実行したい 1 つ目の関数という書き方ができる。
$(document).ready(function1(););
// DOM ロード後に実行したい 2 つ目の関数
$(document).ready(function2(););
....
これと同様に、jQuery を使わない場合でも、以下のように DOM ロード直後に実行する関数を指定できると嬉しい。
domReady(function(){
stop = new Date();
console.log('using domReady ' + (stop - start));
});
////using domReady 5
この原理は、以下の 2 つの関数で達成される。function domReady(f){
// DOM がロードされているときは関数をそのまま実行
if(domReady.done) return f();
// ロード後に実行する関数が複数ある場合は配列に挿入
if(domReady.timer){
domReady.ready.push(f);
}
else {
// DOM がロードされる方がisDomReady で
// 検知される場合より早かった場合の対策。
window.onload = function(){isDomReady();};
// DOM ロード直後に実行する関数の配列の初期化
domReady.ready = [f];
// DOM がロードされているかを定期的にチェック
domReady.timer = setInterval(isDomReady, 13);
}
}
/**
* DOM がロードされているかをチェックする。
*/
function isDomReady(){
if (domReady.done) return false;
// ページ内の DOM 要素がロードされているかをチェックしている。
if (document && document.getElementsByTagName &&
document.getElementById && document.body) {
clearInterval(domReady.timer);
domReady.timer = null;
// 予約された関数を順次実行
for(var i = 0, l = domReady.ready.length; i < l; i++) {
domReady.ready[i]();
}
domReady.ready = null;
domReady.done = true;
}
}
jQuery などのライブラリを使わない場合で、DOM ロード直後に実行する関数を指定したい場合に使えます。

0 comments:
コメントを投稿