にしし ふぁくとりー(西村文宏 個人サイト)

"JavaScript Tips Factory" : Presented by Nishishi. Since 1997.

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

JavaScriptを使って、ウェブページの読み込み完了と同時に何らかの処理をしたい場合など、ページの読込動作とタイミングを合わせて処理を実行したいことがあります。このとき、「ページの読み込み前」・「HTMLの読み込み直後」・「ページの読み込み完了後」など実行タイミングは複数あり、それぞれでJavaScriptの書き方はいくつかあります。それらの記述方法を解説してみます。

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

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

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

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

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

というわけで、上記の3通りについてJavaScriptソースの書き方を以下に紹介してみます。(※3→2→1の順序で解説)

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

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

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

  • 複数のページで同じ処理を行いたい場合に、共通のJavaScriptファイルに1回記述するだけで済むので楽。
  • 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ソースを記述します。

JavaScriptソース

// 処理の中身
function firstscript() {
   alert('ページの読み込みが完了したよ!');
}

// ページの読み込み完了と同時に実行されるよう指定
window.onload = firstscript;

上記のように記述すれば、ウェブページの読み込みが完了した時点で、2~4行目で記述したfirstscript関数が実行されます。
なお、このfirstscript関数を「ページの読み込み直後」以外のシーンで使うことがないのであれば、わざわざ別の関数としては定義せずに、以下のように無名関数として記述する方が楽です。

JavaScriptソース

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

上記の書き方だと、onloadイベントが発生した際に実行されるスクリプトの中身を直接記述していますので、ソースが短く分かりやすくなります。
ちなみに、addEventListenerメソッドを利用して、以下のように記述することもできます。

JavaScriptソース

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

上記の場合、「onload」ではなく「load」なので注意して下さい。
※先程から「onloadイベント」と書いてきましたが、正確にはイベント名としては「load」ですね。(^_^;) loadイベントで実行されるから「on load」なわけで。

ページの読み込みが完了した際に、文字列を変更するサンプル

以下にサンプルを掲載しておきます。上記のサンプルソースのようにalertを使うと少々煩いので、以下のサンプルではinnerHTMLを使って文字列を変更するだけにしています。

▼ページの読み込みが完了すると、表示が「NOW LOADING」から「PAGE LOADED」に変わります。

NOW LOADING…

まあ、先頭からここまで順に読み進めてきた場合は、上記の表示はとっくに「PAGE LOADED」になっているでしょうけども。(^_^;;; この位置を表示した状態でページを再読込すると、ちょっとは見えるかも知れません。^^;

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

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

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

  • できるだけ早く実行された方が望ましい。
  • でも、HTMLソースが読み終わるよりも前に実行されると困る。

といった条件(制約)があります。
このような場合には、以下のような書き方ができます。

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

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

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

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

</body>

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

HTMLソース

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

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

HTMLソース

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

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

HTMLソース

   <script type="text/javascript" src="firstscript.js"></script>
</body>

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

なお、この書き方だと、このscript要素で読み込んでいるスクリプトが読み込み完了するまで「HTMLの読み込み」は終わりません。
後述の(b)の方法も併用している場合は、それだと都合が悪い可能性があります。
そのようなときは、下記のようにscript要素にasync属性を付加しておく手もあります。

<script type="text/javascript" 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関数は事前に書いておきます。
もしくは、下記のように無名関数を使って直接処理を記述しても構いません。(この方が楽でしょう)

JavaScriptソース

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

このように書けば、ウェブページの完全な読み込み完了タイミングではなく、「HTMLだけの読み込みが完了した直後」のタイミングで任意の処理を実行できます。
この書き方の需要が最も多いのではないでしょうかね?(^_^;)

※ただし、DOMContentLoadedイベントはIE8以下では使えないので、古いブラウザへの対処が必要な場合は注意が必要です。(とはいえ、もはやIE8以下は切り捨てても問題ないとは思いますが。) IE以外のメジャーなブラウザでは、かなり昔からサポートされていました。

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

さて、説明するまでもないかも知れませんが、「ウェブページが読み込まれるよりも前」(読み込みが完了するよりも前)に何らかの処理を実行したいなら、HTMLソースの先頭付近にスクリプトを書けば良いわけです。
ウェブページの本文領域(=body要素)ではなく、head要素内で読み込めば良いでしょう。
例えば、以下のように書きます。

HTMLソース

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

※上記のようなアラートボックスが表示されたら、たいていの閲覧者はキレると思いますが。(笑)
HTMLソース内に直接スクリプトを書きたくない場合は、head要素内で外部のJavaScriptファイルを読み込めば良いでしょう。

HTMLソース

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

上記のように書くと、そのJavaScriptファイルの読み込みと実行が完了するまで、HTMLの読み込み処理は止まります。
あまりこのような需要はなさそうな気がしますが。例えば、閲覧者の環境によっては別ページにリダイレクトさせたい場合には、このような位置に記述する方が良いかも知れません。

というわけで、ウェブページの読み込み動作とタイミングを合わせて何か処理したい場合の書き方3種類の紹介でした。

()

JavaScript TIPSふぁくとりーの主要なカテゴリ

下記のカテゴリに区分して、JavaScriptに関するTIPSを公開しています。カッコ内の数字は、該当する記事の件数です。

著者紹介


にしし(西村文宏)

にししでございます。本書いたり記事書いたりしてます。あと萌えたり。著書5冊発売中です(Web製作系4冊+小説1冊)。著書や記事は「西村文宏」名義。記事は主にAll Aboutで連載。本の最新刊は2011年3月に発売されたライトノベルでございますよ。

Twitter:にしし/西村文宏
にしし/西村文宏 on facebook にしし/西村文宏 on mixi にしし/西村文宏 on Google+ フォローはお気軽に!

にしし(西村文宏)連絡先
☕ コーヒーをおごる

著書一覧と詳細

関連するかもしれない情報など

▼このページに関連しそうな記事が約8本くらい自動表示されています。(たぶん)

--- 当サイト内を検索 ---