14.

jQueryの$(document).ready()の使い方|DOM読込後に実行・onloadとの違い

編集

$(document).ready() は、jQueryで「HTML(DOM)の構築が完了したあとに処理を実行する」ためのメソッドです。ページ内の要素をJavaScriptで操作する前に、その要素が確実に存在している状態を待ってからコードを動かすために使います。

この記事の要点
  • $(document).ready(function(){ ... }); は、DOM(HTML要素の構造)が読み込み終わった時点で、中の関数を実行する。
  • 画像やCSS、外部リソースなどの読み込み完了は待たないため、window.onload より早いタイミングで動き始める。
  • $(function(){ ... }); という短縮形でまったく同じ意味になり、実務ではこちらがよく使われる。
  • DOMが未構築のうちに要素を取得・操作しようとすると失敗するため、その対策として用いる。
  • 素のJavaScriptでは DOMContentLoaded イベントが対応する仕組みにあたる。
  • jQuery 3系では $(document).ready(handler) 以外の古い呼び出し方が非推奨・廃止された点に注意する。

 

何をするものか

ブラウザはHTMLを上から順に読み込み、要素を1つずつ解析してDOM(Document Object Model:HTML文書をプログラムから扱えるようにしたツリー構造)を組み立てていきます。$(document).ready() は、このDOMの構築が完了したタイミングを検知し、引数として渡した関数を実行します。

ポイントは「DOMの構築完了」を待つのであって、ページ上の画像・動画・外部CSS・iframeといったリソースのダウンロード完了は待たないことです。そのため、要素の操作やイベント登録といった多くの処理を、できるだけ早い段階で開始できます。たとえば容量の大きな画像が複数あるページでも、画像の読み込みを待たずにボタンの動作設定やテキストの初期化を進められるため、利用者から見た反応が速くなります。

引数に渡す関数は「コールバック関数」と呼ばれ、DOM構築完了という条件が満たされたときにjQueryが呼び出してくれます。つまり、開発者が実行タイミングを自分で計算する必要はなく、「準備ができたら、この処理を動かしてほしい」という形で予約しておくイメージです。

 

基本の書き方

もっとも基本的な形は次のとおりです。ready() に渡した関数(コールバック)の中に、DOM構築後に実行したい処理を書きます。

$(document).ready(function() {
  // DOMの構築が完了してから実行される
  $("#title").text("読み込み完了");
});

 

上の例では、id="title" の要素のテキストを書き換えています。ready() の中に書くことで、その要素がHTML上のどこに記述されていても(たとえば <script> より後ろにあっても)、確実に存在が保証された状態で操作できます。

 

短縮形 $(function(){ ... });

jQueryでは、$() に関数を直接渡すと $(document).ready() と同じ意味になります。記述量が少なく読みやすいため、実務ではこの短縮形が広く使われています。

// 下の2つは同じ意味
$(document).ready(function() {
  // 処理
});

$(function() {
  // 処理(短縮形)
});

 

アロー関数を使って $(() => { ... }); と書くこともできます。どの書き方でも、関数の中身がDOM構築後に実行される点は変わりません。

 

なぜ必要なのか

JavaScriptは、書かれた場所に到達した時点で実行されます。もし <head> 内など、操作したい要素より前にスクリプトを書くと、その要素はまだDOMに存在していません。存在しない要素を取得しようとすると、対象が見つからず処理が空振りになり、操作が反映されない・エラーになるといった不具合につながります。

// 要素より前で実行すると、まだ要素が無いため反映されない例
$("#btn").hide();  // #btn がまだ未構築だと何も起きない

// ready の中に入れれば、構築完了後なので安全
$(function() {
  $("#btn").hide();
});

 

ready() を使えば、スクリプトを書く場所を気にせず、DOM構築後という安定したタイミングで処理を始められます。これが、jQueryのコードを ready() で囲む慣用句が広く使われてきた理由です。とくに、複数のJavaScriptファイルを読み込む構成では、ファイルごとに ready() で囲んでおくことで、どのファイルがどの順番で読み込まれても各処理がDOM構築後に走ることを保証でき、読み込み順に起因する不具合を避けやすくなります。

なお、<script> タグを </body> の直前に置く、あるいは defer 属性を付ける方法でも、要素の存在を確保しやすくなります。ready() はそれらと併用しても問題なく、記述位置に依存しない安全策として機能します。

 

window.onload との違い

$(document).ready() と混同されやすいのが window.onload(jQueryでは $(window).on("load", ...))です。両者は実行タイミングが異なります。

項目 $(document).ready() window.onload
実行タイミング DOM(HTML要素)の構築が完了した時点 画像・CSSなど全リソースの読み込み完了後
画像等の読み込み待ち 待たない 待つ
実行の早さ 比較的早い 比較的遅い
複数登録 複数書くとすべて順に実行される 素の onload への代入は後の記述で上書きされる
主な用途 要素の操作・イベント登録など大半の初期化 画像サイズの取得など、描画後の情報が必要な処理

 

多くの初期化処理は要素さえあれば動くため ready() で十分です。一方、読み込み後の画像の実寸を測りたい場合など、リソースの読み込み完了が前提となる処理では load 側を使い分けます。

 

素のJavaScript(DOMContentLoaded)との対応

jQueryを使わない素のJavaScriptでは、DOMContentLoaded イベントが $(document).ready() に相当します。近年はブラウザの標準機能だけでも同等のことが書けるため、対応関係を押さえておくと役立ちます。

// jQuery
$(function() {
  // 処理
});

// 素のJavaScript(同等)
document.addEventListener("DOMContentLoaded", function() {
  // 処理
});

 

厳密にはイベント発火後の挙動などで細かな差はありますが、「DOM構築完了後に処理を動かす」という目的においては、おおむね同じ役割を果たすものとして対応づけられます。jQueryへの依存を減らしたい場合や、軽量化のためにライブラリを外したい場合は、DOMContentLoaded への置き換えが選択肢になります。

 

ページ読み込みからの流れ

ready() がいつ動くのかは、ブラウザがページを読み込む順序を押さえると理解しやすくなります。大まかな流れは次のとおりです。

順番 起きること 関連する仕組み
1 HTMLを上から解析し、要素を順にDOMへ追加していく
2 DOMの構築が完了する ready() / DOMContentLoaded が発火
3 画像・CSS・外部リソースの読み込みが終わる window.onload / load が発火

 

このように ready() はステップ2、onload はステップ3で動きます。両者の差は、画像など重いリソースの読み込みを待つかどうかであり、待たないぶん ready() のほうが早く反応できます。

 

実務的な使用例

クリックなどのイベント登録も、対象の要素がDOMに存在してから行う必要があるため、ready() の中で設定するのが一般的です。次の例は、ボタンを押すとメッセージを表示する簡単なものです。

$(function() {
  // ボタンにクリックイベントを登録
  $("#sendBtn").on("click", function() {
    $("#message").text("送信しました");
  });
});

 

id="sendBtn" のボタンと id="message" の表示先がHTML上に存在することを ready() が保証するため、イベント登録もテキストの書き換えも確実に機能します。もしこの処理を ready() の外側に書くと、要素がまだ無い段階ではイベントが登録されず、ボタンを押しても反応しないことがあります。

 

落とし穴と注意点

つまずきやすいポイント
  • 複数の ready() は併用できる: $(function(){}) を複数回書いても、それぞれが記述順に実行されます。上書きされて消えることはないため、機能ごとに分けて書いても問題ありません。
  • 要素の取得は ready() の内側で: DOMに依存する要素取得や操作は、必ず ready() のコールバック内に書きます。外側に書くと、まだ要素が無くて動かないことがあります。
  • jQuery 3系での仕様変更: jQuery 3では $(document).ready(handler) の形だけが推奨され、$(document).on("ready", ...) のような古い書き方は廃止されました。バージョンに応じて推奨形を使ってください。具体的な対応はお使いのjQueryの公式ドキュメントで確認することをおすすめします。
  • 読み込み済みでも動く: DOM構築がすでに終わったあとに ready() を登録した場合でも、コールバックは破棄されず実行されます。タイミングを過ぎても処理が失われない設計になっています。

 

よくある質問(FAQ)

Q. $(document).ready()$(function(){}) はどちらを使うべきですか。
A. 動作は同じです。短く書ける後者が好まれる傾向にありますが、可読性やチームの方針に合わせて選んで問題ありません。

Q. ready() を使えば <script> の置き場所はどこでもよいですか。
A. 要素の存在という観点では、ready() の内側に書いた処理はDOM構築後に実行されるため、記述位置に左右されにくくなります。ただしjQuery本体は処理より前に読み込まれている必要があります。

Q. 画像が表示されたあとに処理したい場合はどうしますか。
A. その用途では ready() ではなく $(window).on("load", ...)(または window.onload)を使います。ready() は画像などの読み込み完了を待たないためです。

Q. ready() を書いてもコードが動きません。何を確認すればよいですか。
A. まず、jQuery本体の読み込みが ready() を書いたスクリプトより前にあるかを確認します。$ が定義されていないとエラーになります。あわせて、操作対象の idclass の指定が正しいか、ブラウザの開発者ツールのコンソールにエラーが出ていないかも確認すると原因を切り分けやすくなります。

Q. 複数のファイルに ready() を分けて書いても大丈夫ですか。
A. 問題ありません。ready() は何回登録しても、それぞれが順に実行されます。機能やページごとにファイルを分け、各ファイルで ready() を使う構成も一般的です。

Q. 最近のJavaScriptでも ready() は必要ですか。
A. jQueryを使っているプロジェクトでは引き続き有効で、簡潔に書ける利点があります。一方、jQueryを使わない場合は素のJavaScriptの DOMContentLoaded や、<script> への defer 属性でも同様の目的を達成できます。プロジェクトの構成に合わせて選ぶとよいでしょう。

 

まとめ

$(document).ready() は、DOMの構築が完了したタイミングで処理を実行するためのjQueryの基本機能です。画像などの読み込みを待たずに動くため、要素の操作やイベント登録といった大半の初期化処理を早い段階で安全に始められます。短縮形の $(function(){ ... }); も同じ意味で使え、素のJavaScriptでは DOMContentLoaded が対応します。リソースの読み込み完了が前提となる処理だけ window.onload 側を使い分け、jQueryのバージョンによる推奨形の違いには公式ドキュメントで確認しながら対応するとよいでしょう。

 

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 導入方法
  2. 文法
  3. HTML/CSS 操作・制御
  4. 要素の取得
  5. 値の取得
  6. jQuery で要素を追加(append / prepend / before / after / wrap)
  7. 値と要素の削除
  8. 子要素の削除
  9. 要素のコピー
  10. Ajax
  11. 項目をタッチ/クリックしてスライドさせる方法
  12. テキスト/セレクトボックス/ラジオボタン変更時のイベント
  13. パスワードを一時的に表示させる方法
  14. $(document).ready(function() { ...
  15. セレクトボックスにオプションを追加する方法

最近更新/作成されたページ