JavaScriptを記述する方法はいくつか存在するが、それぞれ実行タイミングが異なる。
ここではそれについてまとめる。
<script>タグ内に記述する
<script>タグ内にJavaScriptを記述した場合、スクリプトが実行されるのは<script>タグが解析された直後となる。そのため<script>タグ以降のDOM要素を操作することはできない。
<body>
<div id="a"></div>
<script>
var a = document.getElementById('a');
console.log(a != null); // true
var b = document.getElementById('b');
console.log(b != null); // false
</script>
<div id="b"></div>
</body>
また、外部のJavaScriptファイルを読み込んだ場合も同様で、<script>タグ解析後にファイル読み込みが開始され、読み込み終了後スクリプトが実行される。
<div id="a"></div>
<script type="text/javascript" src="demo.js"></script>
<div id="b"></div>
var a = document.getElementById('a');
console.log(a != null); // true
var b = document.getElementById('b');
console.log(b != null); // false
##onloadイベントハンドラとして記述する
この場合はページ読み込み完了後、すなわちDOMツリー構築、<img>タグによる画像ファイルの外部リソースのロードなどすべて完了した時点でスクリプトが実行される。
// htmlは先程と同じ
window.onload = function() {
var a = document.getElementById('a');
console.log(a != null); // true
var b = document.getElementById('b');
console.log(b != null); // true <- 注目
};
そのため、画像ファイルなどのリソースが大きい場合、スクリプトの実行までに必要以上の時間がかかる可能性がある。
##DOMContentLoadedイベントに対してリスナを登録する
DOMContentLoadedはDOMツリー構築完了直後、画像ファイルなどの外部リソースが読み込まれる前に発火するイベントである。このイベントに対してリスナ登録することで、イベント発火時にスクリプトを実行する。
document.addEventListener('DOMContentLoaded', function() {
var a = document.getElementById('a');
console.log(a != null); // true
var b = document.getElementById('b');
console.log(b != null); // true
});
なお、DOMContentLoadedは、IE9、Safari3.1以降でないと対応していない模様。
DOMContentLoaded - MDN
##動的ロード
script要素を生成することにより、動的にJavaScriptファイルをロードすることのできる記述方法。JavaScriptファイルのダウンロードから実行開始まで、その他の処理をブロックしないという特徴がある。
var script = document.createElement('script');
script.src = 'test.js';
document.body.appendChild(script);
なお、この記述方法は、クロスドメインでデータ取得を行う場合に利用されるJSONPという仕組みの実現にも使われる、らしい。。。
##参考書籍
パーフェクトJavaScript