「ページを開いたときに一度だけ実行したい」処理は、いつ実行されるか(タイミング)を意識すると安定します。DOMがまだ無いうちに要素を操作しようとして失敗する、というのはよくあるミスです。
DOMContentLoaded(または defer スクリプト)。画像など全リソースを待つなら load。なお、「ページを開くたび毎回」と「初回アクセスだけ」は別物で、後者は localStorage で制御します。基本:DOMContentLoaded(DOM構築後・推奨)
HTMLのDOM構築が終わった時点で実行されます。画像の読み込みを待たないため速く、DOM操作やUI初期化はこれで十分です。
document.addEventListener("DOMContentLoaded", () => {
console.log("DOMの構築が完了しました");
// 要素の取得・表示切り替えなど
});
画像まで待つ:load
画像・CSS・スクリプトなどすべてのリソースが読み込まれた後に実行したいときはload イベントを使います。サイズ計算など画像の読み込みが必要な処理に向いています。
window.addEventListener("load", () => {
console.log("ページの読み込みが完了しました(画像も含む)");
});
イベントを使わない方法:deferスクリプト
実は、<script> に defer を付けるか、<body> の最後に置けば、DOM構築後に実行されます。この場合 DOMContentLoaded で囲まなくてもDOM操作ができます。type="module" のスクリプトも同様に defer 相当で動きます。
<!-- head に置いてもDOM構築後に実行される --> <script src="app.js" defer></script> <!-- type="module" も defer 相当 --> <script type="module" src="app.mjs"></script>
落とし穴:発火後に登録すると動かない(readyState)
DOMContentLoaded がすでに発火した後にリスナーを登録すると、イベントは二度と発火しないため処理が実行されません。非同期(async)で読み込まれるスクリプトなどで起こりがちです。document.readyState で状態を確認し、すでに構築済みならその場で実行します。function init() {
// DOM操作・初期化処理
}
if (document.readyState === "loading") {
// まだ読み込み中 → イベントを待つ
document.addEventListener("DOMContentLoaded", init);
} else {
// すでに構築済み → 即実行(これが無いと動かないことがある)
init();
}
これは jQuery の $(function(){}) が内部でやっていることと同じで、いつ読み込まれても確実に動く安全な書き方です。
↓ いま見ているこのページの実際の状態です(readyState はloading → interactive → complete と変化します):
document.readyState:–- DOMContentLoaded:–
- load(全リソース):–
「毎回」と「初回アクセスだけ」は違う
DOMContentLoaded や load はページを開くたびに毎回実行されます。「初回アクセスのときだけ」にしたいなら、localStorage にフラグを保存して制御します。
document.addEventListener("DOMContentLoaded", () => {
if (!localStorage.getItem("visited")) {
// 初回だけ実行したい処理
localStorage.setItem("visited", "true");
}
});
alert() を使うと操作を止めてしまいます。実際は要素の表示で見せるのがおすすめです。初回訪問時だけ要素を見せる具体的な方法(リセットや期限付き表示を含む)は初回訪問時のみ要素を表示する方法、localStorage の基本はlocalStorageの使い方完全ガイドを参照してください。jQueryを使っている場合(ready)
jQueryなら $(document).ready()(または短縮形)で、DOMContentLoaded と同じタイミングで実行できます。
$(function () {
console.log("jQueryでページ読み込み完了");
});
方法の使い分け(まとめ表)
| 方法 | 実行タイミング | 用途 |
|---|---|---|
DOMContentLoaded |
DOM構築後(速い) | DOM操作・UI初期化(基本これ) |
load |
全リソース読み込み後 | 画像サイズ計算など |
defer / 末尾に配置 |
DOM構築後 | イベントで囲まずに実行 |
localStorage 併用 |
初回アクセス時だけ | 「一度きり」の制御 |
jQuery $(function(){}) |
DOM構築後 | jQuery使用時 |
よくある質問(FAQ)
DOMContentLoaded または load のコールバックに書きます。DOMContentLoaded はDOM解析完了後、load は画像など全リソースの読み込み完了後に発火します。どちらもページを開くたびに1回実行されます。DOMContentLoaded はHTMLのDOM解析が終わった時点、load は画像・CSS・スクリプトなど全リソースが読み込まれた後に発火します。DOM操作なら DOMContentLoaded で十分なことがほとんどです。defer を付けるか、<body> の最後に置けばDOM構築後に実行されるため、DOMContentLoaded で囲まなくてもDOM操作ができます。type="module" も同様です。localStorage にフラグを保存し、無いときだけ処理します。DOMContentLoaded 等は毎回実行されるので、「一度きり(初回のみ)」にしたいときは localStorage を併用します。if (document.readyState !== "loading") { init(); } のように、すでに構築済みなら即実行する分岐を入れると確実です。まとめ
ページ読み込み後の処理は、DOM操作なら DOMContentLoaded(または defer スクリプト)、画像まで待つなら load が基本です。
DOMContentLoaded / load は毎回実行されます。「初回アクセスのときだけ」にしたいなら localStorage で制御しましょう。タイミングを正しく選んで、安定した処理にしましょう。

