Posted at

【JavaScript】記述方法別の実行タイミングについて

More than 5 years have passed since last update.

JavaScriptを記述する方法はいくつか存在するが、それぞれ実行タイミングが異なる。

ここではそれについてまとめる。


<script>タグ内に記述する

<script>タグ内にJavaScriptを記述した場合、スクリプトが実行されるのは<script>タグが解析された直後となる。そのため<script>タグ以降のDOM要素を操作することはできない。


html

<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>タグ解析後にファイル読み込みが開始され、読み込み終了後スクリプトが実行される。


html

<div id="a"></div>

<script type="text/javascript" src="demo.js"></script>
<div id="b"></div>


demo.js

var a = document.getElementById('a');

console.log(a != null); // true
var b = document.getElementById('b');
console.log(b != null); // false


onloadイベントハンドラとして記述する

この場合はページ読み込み完了後、すなわちDOMツリー構築、<img>タグによる画像ファイルの外部リソースのロードなどすべて完了した時点でスクリプトが実行される。


demo.js

// 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ツリー構築完了直後、画像ファイルなどの外部リソースが読み込まれる前に発火するイベントである。このイベントに対してリスナ登録することで、イベント発火時にスクリプトを実行する。


demo.js

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