JavaScript

ページの読み込み前・直後・完了時にスクリプトを実行する方法いろいろ

 ウェブページの読み込み完了と同時に何らかの処理をしたい場合など、「ページの読み込み動作」とタイミングを合わせて特定の処理を実行させたいことあります。このとき、JavaScriptを記述する方法はいくつかあります。

 「ウェブページの読み込みタイミング」と「スクリプトを実行するタイミング」の関係としては、例えば以下のような場合があるでしょう。

  1. 前:ウェブページが読み込まれる前に何らかの処理をする。
  2. 直後:ウェブページの HTMLが読み込み完了できた時点で何らかの処理をする。
  3. 完了後:ウェブページ上に掲載されたあらゆるオブジェクト(画像など)の読み込みがすべて完了した後で何らかの処理をする。

 「ページの読み込みが完了した時点」としか言わない場合、上記2のことなのか3のことなのか区別しづらいですが、「onload」というイベントが指し示すのは上記3の「ページ上のあらゆる物体の読み込みが完了した後」という時点です。

 しかし、最も需要が多いのは上記2のケースのような気がします。これは「DOMContentLoaded」というイベント名で表されます。私はそのタイミングで何かを実行させたい場合が多いです。ウェブページ上に画像などの読み込み物が多い場合は、3のタイミングはずいぶん後にならないと発生しませんから。

1.【前】:ウェブページが読み込まれる前に何らかの処理をする方法

 さて、説明するまでもないかも知れませんが、「ウェブページが読み込まれるよりも前」(読み込みが完了するよりも前)に何らかの処理を実行したいなら、HTMLソースの先頭付近にスクリプトを書けば良いわけです。

 ウェブページの本文領域(=body要素)ではなく、head要素内で読み込めば良いでしょう。

 例えば、以下のように書きます。

HTML source


<head>
	<script>
		// ページの読み込み完了を待たずに即実行する処理
		alert('これからウェブページの読み込みを始めます');
	</script>
	 :
	 :
</head>

※上記のようなアラートボックスが表示されたら、たいていの閲覧者は不快になるはずですが…

 HTMLソース内に直接スクリプトを書きたくない場合は、head要素内で外部の JavaScriptファイルを読み込めば良いでしょう。

HTML source


<head>
	<script src="firstscript.js"></script>
	 :
	 :
</head>

 上記のように書くと、その JavaScriptファイルの読み込みと実行が完了するまで、HTMLの読み込み処理は止まります。

 あまりこのような需要はなさそうな気がしますが。例えば、閲覧者の環境によっては別ページにリダイレクトさせたい場合には、このような位置に記述する方が良いかも知れません。

2.【直後】:ウェブページの HTMLが読み込み完了できた時点で何らかの処理をする方法

 さて、先ほどの onloadイベントを使う方法では、ページ上に存在する画像など「すべてのオブジェクト」の読み込みが完了するまで処理は実行されません。しかし、その方法だと、「ページの大きさ」や「掲載されている画像のファイルサイズ」などによっては、スクリプトが実行されるまでに結構な待ち時間が発生する場合もあります。ナビゲーションメニューを提供するスクリプトなど、「HTMLさえ全部読み込まれていれば、ページ上の画像などの読み込みを待つ必要は無い」という場合もあるでしょう。

 例えばページのナビゲーションに利用するスクリプトなど、ページ上の表示を動的に変更するような処理の場合は、

といった条件(制約)があります。

このような場合には、以下のような書き方ができます。

 先程の onloadイベントが「ウェブページ上のあらゆる物体の読み込みが完了したタイミング」だったのに対して、DOMContentLoadedイベントは「ウェブページの HTMLを最後まで読んだ直後のタイミング」を示します。この方法なら、画像などの読み込みは一切待たずに、単に HTMLを最後まで読めた時点でスクリプトを実行できます。これが上記(b)の方法です。

 それ以前に、そもそも HTMLソースの末尾にスクリプトを書けるのであれば、(a)の方法を使うのが楽です。

 1ページだけでしか使わないスクリプトの場合は前者(a)の方法を使えば手軽で良さげです。しかし、サイト内の共通スクリプトなどに書く場合など、HTMLソースに手を加えられない場合は(b)の方法を使うと良いでしょう。

(a) HTMLの末尾(=</body>要素の直前)でスクリプトを実行するように書く方法

 HTMLの本文の末尾には、以下のように body要素の終了タグがあるはずです。


</body>

 この直前で(=HTMLソースの末尾付近で)、以下のようにスクリプト本体を書けば良いだけです。

HTML source


	<script>
		// HTMLを最後まで読み終わってから実行する処理
		alert("HTMLの読み込みが完了した瞬間です。");
	</script>
</body>

 処理を関数にしている場合は、以下のようにして呼び出せば良いでしょう。

HTML source


	<script>
		// HTMLを最後まで読み終わってから実行する処理
		firstscript();
	</script>
</body>

 もし、実行したい処理が外部の JavaScriptファイルに存在する場合(※この用途ではたいていそうでしょう)は、以下のように、HTMLソースの末尾で JavaScriptファイルを読み込めば良いです。

HTML source


	<script src="firstscript.js"></script>
</body>

 要するに、特に onloadなどのイベントには合わせずに、HTMLソース内に直接スクリプトを記述すれば(または関数を呼び出す記述を書けば)、そこを読み込んだ瞬間に実行されるわけです。なので、HTMLソースの末尾にスクリプトを書けば、HTMLが最後まで読み込まれた段階で(※ページ内の画像など「その他のオブジェクト」の読み込みが済んでいるかどうかに関係なく)すぐに実行されます。

 なお、この書き方だと、この script要素で読み込んでいるスクリプトが読み込み完了するまで「HTMLの読み込み」は終わりません。

 後述の(b)の方法も併用している場合は、それだと都合が悪い可能性があります。

 そのようなときは、下記のように script要素に async属性を付加しておく手もあります。


<script src="firstscript.js" async></script>

 このように書いておくと、指定のスクリプトは非同期で読み込まれるので、このスクリプトの読み込み完了を待つことなくHTMLの読み込みは進行します。

(b) JavaScriptソースに DOMContentLoadedイベントのタイミングで実行されるように書く方法

 さて、HTMLソース側にスクリプトを追記できるなら先の(a)の方法でも良いのですが、HTMLソース側には何も追記せずに JavaScript側だけで「HTMLの読み込み完了直後」のタイミングで何かの処理を実行させたい場合もあります。

 そのような場合には、DOMContentLoadedというタイミングでスクリプトが実行されるよう JavaScriptを書けば済みます。

 DOMContentLoadedイベントは「ウェブページの HTMLを最後まで読んだ直後のタイミング」を示します。この方法なら、画像などの読み込みは一切待たずに、単に HTMLを最後まで読めた時点でスクリプトを実行できます。


document.addEventListener("DOMContentLoaded", firstscript );

 上記のソースでは、addEventListenerメソッドを使って「DOMContentLoaded」イベントが発生したタイミングで firstscript関数を実行するよう指定しています。firstscript関数は事前に書いておきます。

 もしくは、下記のように無名関数を使って直接処理を記述しても構いません。(この方が楽でしょう)


document.addEventListener("DOMContentLoaded", function() {
	// 実行したい処理
});

 このように書けば、ウェブページの完全な読み込み完了タイミングではなく、「HTMLだけの読み込みが完了した直後」のタイミングで任意の処理を実行できます。

jQueryの場合

 ページの他のデータ(画像など)を読み込み完了前、DOMを読み込み時(ready)に実行。


$(document).ready(function(){
	alert('ページの読み込みが完了したよ!');
});

 2度実行すると、両方実行されます。


$(document).ready(function(){
	alert('①ページの読み込みが完了したよ!');
});

$(document).ready(function(){
	alert('②ページの読み込みが完了したよ!');
});

 省略して書くと、


$(function() {
	alert('ページの読み込みが完了したよ!');
});

3.【完了後】:ウェブ上のあらゆるオブジェクトの読み込みがすべて完了した後で処理をする方法

 ウェブページ上に掲載された「すべてのオブジェクト(画像などを含む)の読み込みが完了」した時点で何らかの処理をしたい場合は、onloadイベントに合わせてスクリプトが実行されるように記述する方法があります。

 これには、例えば以下の記述方法があります。

 どちらも効果は同じです。1ページだけでしか使わない場合は前者Aの方法が手軽です。が、後者Bの場合だと、HTMLとスクリプトを分離できるので、

などのメリットがあります。

(A) HTMLで body要素に「onload」属性を指定することで、読み込み完了時に処理をする方法

 onload属性を使う場合は、以下のように HTMLを書きます。


<body onload="firstscript();">

 上記のように記述すれば、読み込みが完了した時点で、firstscript関数が実行されます。

 関数を別途用意するまでもない場合は、下記のように属性値に直接スクリプトを書くこともできます。


<body onload="alert('ページの読み込みが完了したよ!');">

 このとき、onload属性の値を二重引用符(ダブルクォーテーション記号)で囲んでいるなら、中身の JavaScriptソース中で引用符が必要になった場合は、シングルクォーテーション記号を使います。ソース中でダブルクオーテーション記号を使ってしまうと、そこで onload属性の値が終わったと判断されてしまって、うまく動きません。

(B) JavaScriptソースに window.onloadメソッドを利用して、値に処理を書く

 HTMLソースに手を加えることなく、JavaScript側だけで onloadイベントを使って何らかの処理を実行したい場合は、以下のように window.onloadメソッドを使って JavaScriptソースを記述します。


// 処理の中身
function firstscript() {
	alert('ページの読み込みが完了したよ!');
}
 
// ページの読み込み完了と同時に実行されるよう指定
window.onload = firstscript;

 上記のように記述すれば、ウェブページの読み込みが完了した時点で、2~4行目で記述した firstscript関数が実行されます。

 なお、この firstscript関数を「ページの読み込み直後」以外のシーンで使うことがないのであれば、わざわざ別の関数としては定義せずに、以下のように無名関数として記述する方が楽です。


window.onload = function() {
	// 実行したい処理
	alert('ページの読み込みが完了したよ!');
}

 上記の書き方だと、onloadイベントが発生した際に実行されるスクリプトの中身を直接記述していますので、ソースが短く分かりやすくなります。

 同じスクリプト内で2度実行すると、行数が後ろの方のみ実行されます。


window.onload = function() {
	alert('①ページの読み込みが完了したよ!');
}

window.onload = function() {
	alert('②ページの読み込みが完了したよ!');
}

この場合、「②ページの読み込みが…」のみ表示されます。

 ちなみに、addEventListenerメソッドを利用して、以下のように記述することもできます。


document.addEventListener("load", function() {
	// 実行したい処理
	alert('ページの読み込みが完了したよ!');
});

 上記の場合、「onload」ではなく「load」なので注意して下さい。

 load時に読み込ませる jQueryの書き方


$(window).on('load',function(){
	alert('ページの読み込みが完了したよ!');
});