こんにちは。ビンゴ豊島です。デザイナーという立場ですがJavaScriptもちょいちょいと書かせていただいております。
今回はDOM操作をする前に知っておきたいDOMの読み込みについて記事を書かせていただきます。対象はDOM操作ばかり、もしくはDOM操作しかしないんですけど?といったデザイナーさんになります。これを読むと今までなんとなく使っていたjQueryも意味を理解した上で使えるようになれるかもしれません。
Webページが表示されるまで
ブラウザがページを表示するまで簡単に書くと下記のようになります。
- サーバにページをリクエスト
- サーバから返されたHTMLをダウンロード
- DOM構築をしつつ描画と画像等のダウンロード
- 表示完了
このうち「3. DOM構築をしつつ描画とダウンロード」のタイミングでどのような順番でイベントや処理が発生するかを検証します。
DOMの読み込みを確認するサンプルコード
読み込まれたタイミングや任意のタイミングでコンソールに出力するJavaScriptを記述しています。記述方法は下記3通りです。
- インラインに直接
- window.load時
- 外部JavaScriptに記述したjQueryの$(function(){});
※jQueryのready()と同じ動作
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Demo</title> <link rel="stylesheet" href="demo.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="demo.js"></script> <script> console.log("インラインhead内"); window.onload = function(){ console.log("Window onload"); } console.log($("header").get(0)); </script> </head> <body> <header> <h1>Demo</h1> </header> <div> <article> <h2>スマートフォンアプリ開発</h2> <p>多数のiPhone、Androidアプリの開発・運用経験を活かし、企画からデザイン・開発・運用、プロモーションまで一連のノウハウを蓄積しております。お客様は企画に集中していただけるようワンストップサービスをご提供いたします。</p> </article> <script> console.log("インラインコンテンツ内"); console.log($("header").get(0)); </script> <article> <h2>スマホサービス構築パック</h2> <p>アプリ開発の経験を活かした流行るアプリサービスを作ります。アプリビジネス・パートナーとして立ち上げから運用開始まで売上拡大に向けて二人三脚で支援します</p> </article> <article> <h2>月額課金アプリパック</h2> <p>話題の月額継続課金アプリの企画から開発、そして煩雑な申請作業、さらには運用までワンストップでご提供致します。成功する月額課金アプリをご提供します。</p> </article> </div> <footer> <p>© 2013</p> </footer> <script> console.log("インラインコンテンツ最後"); console.log($("header").get(0)); </script> </body> </html> |
|
1 2 3 |
$(function(){ console.log("外部JS"); }); |
このコードをブラウザで表示するとこのようになります。コンソールに注目です。
DOM構築時に呼び出されるJavaScriptの順番
サンプルコードを実行するとコンソールに以下の順番で表示されます。
- インラインhead内
- undefined
- インラインコンテンツ内
- <header></header>
- インラインコンテンツ最後
- <header></header>
- 外部JS
- Window onload
コードは上から下へ順次処理されていきますのでインラインで直接記述している箇所はその順番でコンソールに表示されます。7と8はイベント発生時に実行していますのでこの順番でイベントが発生したことになります。
インラインでDOM操作をする
先程の順番で1-6まではインラインでJavaScriptを記述しています。このうち2が「undefined」となってしまいました。2ではHTMLのhead内でbody内のheaderタグを取得するJavaScriptを記述しています。一方同じ処理を記述した4と6はきちんとheaderタグを取得できています。
これはコードの上から下へ順次処理がされているためで、2のJavaScriptを実行するタイミングではまだheaderタグの読み込みが完了していない結果undefinedが返されます。headerタグよりも後に記述した4と6は既にheaderタグのDOM解析が完了しているためきちんとheaderタグを取得できています。
DOMのイベント
先ほどのようにインラインで直接記述する場合は必ず取得したいHTML Elementが読み込まれた後にJavaScriptを記述する必要がありますが、DOMの読み込み完了後、ウィンドウの読み込み完了後といったイベントを使えば外部のJavaScriptやHTMLのhead内など好きな場所へコードを記述できるようになります。これは「DOM構築時に呼び出されるJavaScriptの順番」の7と8になります。
jQuery(function(){})
|
1 2 3 |
$(function(){ }); |
7で使用したjQueryでよく見かけるこのコードですが、この中にコードを書くとDOMの読み込み完了後に呼び出されます。HTMLの最後まで読み込んだら呼び出されると捉えてもよいでしょう。この読み込みには当然画像等は含まれません。そのため画像の読み込みが終わるまで待たされる、といったこともなくDOM解析が完了した時点で即座に実行されます。
またjQueryを使わなくともDOMContentLoadedというものが存在しますが、こちらはIE8以下で動作しません。
DOMのイベント window.onload
8で使用したこのコードはウィンドウ内全ての読み込みが完了した時に発生するイベントです。重い画像や大量の画像があった場合も最後まで読み込みが終わらなければ呼び出されません。そのため今回のサンプルコードでは一番最後に呼び出されています。
まとめ
今回のサンプルコードの場合実行される順番は下記の様になります。
- インライン
- jQuery $(function(){}) DOM読み込み完了後
- window.onload Windowの読み込み完了後
これらを踏まえ適切なタイミングにDOM操作をするとよりDOMやjQueryに関して理解した上で処理を書けるようになるかと思います。
また、UI等であれば表示されているのにマウスやタップ操作をしても暫く反応しないといったことにもなりますので出来るだけ早く処理が走るようにする、準備が整うまで画面に表示しない等の考慮が必要です。