もくじ
Webページを作成する際、JavaScriptで「ページの読み込みが完了したタイミングで処理を実行したい」「画像やリソースの読み込みが終わった後に何かしたい」と思ったことはありませんか?
ページの読み込みや表示に関するイベントにはいくつか種類があり、それぞれ発火するタイミングや用途が異なります。
本記事では、readystatechange
、DOMContentLoaded
、load
、pageshow
といった主要なイベントの違いや使い分け、実際のサンプルコードを交えて分かりやすく解説します。
「どのイベントを使えばいいのか分からない」「発火タイミングの違いを知りたい」という方は、ぜひ参考にしてください。
ページ読み込み・ページ表示関連イベントの発火タイミング
この記事では、readystatechange、DOMContentLoaded、load、pageshowイベントの発火順序を紹介します。
ページ読み込み・ページ表示関連イベントの発火順序
readystate: loading
ページの読み込みが開始された段階
※HTMLのダウンロードが始まり、まだDOMの構築が完了していない状態readystatechange: interactive
DOMの構築が完了し、ユーザーがページのコンテンツにアクセスできる状態
まだ画像やスタイルシートなどのリソースは読み込まれていない可能性があるDOMContentLoaded
HTMLの解析とDOMツリーの構築が完了した段階
※外部リソース(画像やスタイルシートなど)はまだ読み込み中の場合もあるreadystatechange: complete
ページ内のすべてのリソース(画像やスタイルシート、サブフレームなど)が完全に読み込まれた段階
load
ページ全体の読み込みが完全に終わり、すべてのリソース(外部ファイルを含む)が利用可能になった段階
pageshow
ページが表示されたときに発火
※新規ロードだけでなく、ページがキャッシュから復元された場合にも発火します
readystatechange: interactiveとDOMContentLoadedの違い
readystatechange: interactive
≒DOMContentLoaded
ですが、少し違いがあります。
readystatechange: interactiveはdocument.readyStateがinteractiveに変わることを意味します。これは、DOMの解析が完了し、ユーザーがインタラクション(操作)を開始できる状態になったことを示します。
DOMContentLoadedイベントは、DOMの構築が完了し、すべてのHTMLが読み込まれて解析されたときに発火します。
DOMContentLoadedは、DOMの準備が整ったときに発火するものであり、この時点でdocument.readyStateはinteractiveまたはそれ以降の状態であるため、DOMContentLoadedがreadystatechange: interactiveよりも早く発火することは通常ありません。
readystatechange: completeとloadの違い
readystatechange: complete
≒load
ですが、少し違いがあります。
readyState プロパティが 'complete' になるのは、ドキュメントの全てのリソースが読み込まれた時点を指します。具体的には、DOM ツリーが構築され、すべてのサブリソース(画像、スタイルシート、スクリプトなど)の読み込みが完了したときに発生します。
※外部リソース(動画やiframe内のコンテンツなど)は含まれない場合があります。
load イベントは、ページ上のすべてのリソース(画像、スタイルシート、スクリプト、外部リソース)の読み込みが完了した後に発生します。
ページ読み込み・ページ表示関連イベントの発火タイミング検証用コード
イベントの発火までに掛かった時間を計測し、コンソールで確認できるようにコードを調整しました。
// ページ読み込み開始時点のタイムスタンプを取得
const startTime = performance.now();
function logTime(eventName) {
const currentTime = performance.now();
console.log(`${eventName} - 発火までの時間: ${currentTime - startTime} ms`);
}
// readyStateの現在の状態
if (document.readyState === 'loading') {
logTime('readystate: loading');
}
// readystatechangeイベントの状態変化の監視
document.addEventListener('readystatechange', function() {
logTime(`readystatechange: ${document.readyState}`);
});
// DOMContentLoadedの監視
document.addEventListener('DOMContentLoaded', function() {
logTime('DOMContentLoaded');
});
// loadイベントの監視
window.addEventListener('load', function() {
logTime('load');
});
// pageshowイベントの監視
window.addEventListener('pageshow', function() {
logTime('pageshow');
});
readystatechangeイベントの使用方法
readystatechangeイベントは、読み込み状態が変わるたびに発生します。
document.readyStateプロパティを使用して、現在の状態を確認できます。主要な状態は以下の通りです。
- loading
- ドキュメントが読み込まれている途中。
※readystatechange
イベントは読み込み状態が変わるたびに発生するため、loading
を検知することはできません。
- interactive
- ドキュメントが完全に読み込まれたが、他のリソースはまだ読み込み中。
- complete
- ドキュメントとすべてのリソース(画像、スタイルシートなど)が完全に読み込まれた状態。 ※外部リソースは除く
addEventListenerメソッドを使った書き方
addEventListenerメソッドを使用することで、同じイベントに対して複数のリスナーを追加できるため、複数の処理を同時に行うことが可能です。
一般的にはaddEventListener
の使用が推奨されます。
document.addEventListener('readystatechange', function() {
if (document.readyState === 'interactive') {
// 例えば、ユーザーが操作可能になるタイミングで実行したい処理
console.log('DOMの構築が完了');
} else if (document.readyState === 'complete') {
// すべてのリソースが読み込まれた後に実行する処理
console.log('すべてのリソースが読み込み完了');
}
});
onreadystatechangeプロパティを使った書き方
このプロパティには1つのイベントハンドラーしか設定できません。
既存のハンドラーを上書きしてしまう可能性があります。
document.onreadystatechange = function() {
if (document.readyState === 'interactive') {
console.log('DOMの構築が完了');
// 例えば、ユーザーが操作可能になるタイミングで実行したい処理
} else if (document.readyState === 'complete') {
// すべてのリソースが読み込まれた後に実行する処理
console.log('すべてのリソースが読み込み完了');
}
};
DOMContentLoadedイベントの使用方法
DOMContentLoadedは、HTML文書が完全に読み込まれ、DOM解析されたときに発火するイベントです。
画像やスタイルシート、その他のリソースがすべて読み込まれた後ではなく、HTMLの構造が完全に解析された時点で発火します。
このイベントは、DOMの構造が整ってからスクリプトを実行するため、DOM要素が存在しない状態でスクリプトを実行してエラーが発生するのを防ぐことができます。
addEventListenerメソッドを使った書き方
document.addEventListener('DOMContentLoaded', function() {
// DOMが完全に読み込まれたときに実行するコード
console.log('DOMが完全に読み込まれました');
});
loadイベントの使用方法
loadイベントは、HTML文書全体や特定のリソース(画像、スクリプト、スタイルシートなど)が完全に読み込まれた後に発火します。
DOMContentLoadedイベントがDOMが構築されたときに発火するのに対し、loadイベントは、ページ内のすべてのリソースが読み込まれたときに発生します。
addEventListenerメソッドを使った書き方
addEventListenerメソッドを使用することで、同じイベントに対して複数のリスナーを追加できるため、複数の処理を同時に行うことが可能です。
一般的にはaddEventListener
の使用が推奨されます。
window.addEventListener('load', function() {
console.log('すべてのリソースが読み込まれました');
});
onloadプロパティを使った書き方
このプロパティには1つのイベントハンドラーしか設定できません。
既存のハンドラーを上書きしてしまう可能性があります。
window.onload = function() {
console.log('すべてのリソースが読み込まれました');
};
画像などのリソースが読み込まれたときに発火させる
let img = document.querySelector('img');
if (img.complete) {
// 画像が既に読み込まれている場合
console.log('画像が既に読み込まれています');
} else {
// 画像が読み込まれていない場合
img.addEventListener('load', function() {
console.log('画像が読み込まれました');
});
}
loadイベントの用途
画像や外部リソースが完全に読み込まれた後でなければ処理を行いたくないケースで使用されます。
例えば、すべての画像が表示されてからレイアウトの調整やアニメーションを開始するような場合です。
loadイベントの注意点
loadイベントはページ全体のリソースが読み込まれるまで待機するため、動作が遅れる可能性があります。
DOMが準備された時点で処理を開始したい場合は、DOMContentLoadedイベントを使う方が適しています。
pageshowイベントの使用方法
pageshowイベントは、ウェブページが表示されたときに発火するイベントです。ページが再読み込みされるとき、またはキャッシュから復元されるときに発生します。
特に、ブラウザの「戻る」や「進む」ボタンを使った場合に、キャッシュされたページが表示される際にもトリガーされるため、通常の load イベントとは異なります。
addEventListenerメソッドを使った書き方
pageshowイベントは、通常windowオブジェクトにバインドして使用します。
addEventListenerメソッドを使用することで、同じイベントに対して複数のリスナーを追加できるため、複数の処理を同時に行うことが可能です。
一般的にはaddEventListener
の使用が推奨されます。
window.addEventListener('pageshow', function(event) {
console.log('ページが表示されました');
});
onpageshowプロパティを使った書き方
このプロパティには1つのイベントハンドラーしか設定できません。
既存のハンドラーを上書きしてしまう可能性があります。
window.onpageshow = function(event) {
console.log('ページが表示されました');
};
persistedプロパティでページがキャッシュから復元されたかどうかを判定
window.addEventListener('pageshow', function(event) {
if (event.persisted) {
console.log('ページがキャッシュから復元されました。');
} else {
console.log('ページが通常のロードで表示されました。');
}
});
pageshowイベントの用途
- キャッシュされているページの状態をリセットする
ユーザーがブラウザの「戻る」ボタンを使用した際に、ページが再表示されたときに必要な初期化処理を行いたい場合。 - フォームの再送信防止
ページがキャッシュから復元される場合に、フォームのデータをリセットするなどの処理を行うことができます。 - アニメーションやスクロール位置のリセット
キャッシュから復元されたページで、アニメーションやスクロール位置をリセットするために使用できます。
まとめ
ページの読み込みや表示に関するJavaScriptイベント(readystatechange
、DOMContentLoaded
、load
、pageshow
)は、それぞれ発火タイミングや用途が異なります。
正しく使い分けることで、ユーザー体験の向上やバグの防止につながります。
- DOMContentLoaded:DOM構造が完成したタイミングで初期化処理を行いたい場合に最適
- load:画像や外部リソースも含めてすべての読み込み完了後に実行したい処理に最適
- pageshow:キャッシュ復元時も含めてページ表示時の処理が必要な場合に便利
- readystatechange:細かい状態変化を監視したい場合に活用
それぞれの特徴を理解し、目的に応じて適切なイベントを選択しましょう。