JavaScriptが実行されるタイミングとしては、大きく分けて以下の4種類あります。
- 直ぐに実行
- DOMの読み込み完了後(DOMContentLoaded)
- CSSや画像など、ページで使用しているリソースを全て読み込んだ後(load)
- ユーザーが特定の操作をした後(click, scroll, resize など)
今回は上記のうち、ユーザーが操作したタイミング以外の3点について試してみたいと思います。
今回試す内容に関して、特に補足のない限りhead内で記述している点ご注意ください。
直ぐに実行
通常記述をした場合、そのコードは直ぐに実行されます。
以下の場合、ユーザーエージェントの情報をconsoleに表示します。
1 2 | const ua = navigator.userAgent.toLowerCase(); console.log(ua); |
上記のような場合は問題ないですが、例えばDOM要素に対して操作などを行おうとした場合、DOM要素より前に記述があると操作ができません。
1 | document.getElementById( 'header' ).style.color = 'red' ; |
1 | < header id = "header" >ヘッダー</ header > |
DOM要素の前にJavaScriptの記述がある場合のデモページ
DOM要素の後に記述がある場合は操作できます。
1 2 3 4 | < header id = "header" >ヘッダー</ header > < script > document.getElementById('header').style.color = 'red'; </ script > |
DOM要素の後にJavaScriptの記述がある場合のデモページ
DOMContentLoaded
次にDOMContentLoadedですが、DOMの読み込み完了後に実行されます。
直ぐに実行する例だとhead内に記述した場合操作ができませんでしたが、DOMContentLoadedを使用した場合はDOMの読み込み完了後に実行されることになるので操作できます。
1 2 3 | document.addEventListener( 'DOMContentLoaded' , function () { document.getElementById( 'header' ).style.color = 'red' ; }); |
1 | < header id = "header" >ヘッダー</ header > |
後述するloadとの違いとしては、loadは外部リソースも含めて読み込み完了した後に実行される点です。
例えば画像のサイズを取得して何らかの処理を行おうとした場合、DOMContentLoadedだと外部リソースが読み込まれているかはわからないので、サイズを取得できない場合があります。
1 2 3 4 | document.addEventListener( 'DOMContentLoaded' , function () { const imgW = document.getElementById( 'img' ).naturalWidth; console.log(imgW); }); |
1 | < img src = "../img.jpg" id = "img" > |
ページアクセスが2回目以降だと画像のキャッシュが残るため、サイズ取得ができやすいので注意が必要です。
DOMContentLoadedで画像サイズを取得した場合のデモページ
load
loadは前で記載したように、ページで使用しているリソースを全て読み込んだ後に実行されます。
前述の画像サイズを取得する例の場合、loadを使用すると問題なく取得できます。
1 2 3 4 | window.addEventListener( 'load' , function () { const imgW = document.getElementById( 'img' ).naturalWidth; console.log(imgW); }); |
loadを使用する方法としては addEventListener() ではなくwindow.onload = function() {〜}; といった書き方もありますが、この場合は複数あると後述の内容で上書きされてしまうため、 addEventListener() を使用する方がよさそうです。
1 2 3 4 5 6 7 8 9 10 11 12 | window.addEventListener( 'load' , function () { console.log( 'addEventListener 1回目' ); }); window.addEventListener( 'load' , function () { console.log( 'addEventListener 2回目' ); }); window.onload = function () { console.log( 'window.onload 1回目' ); // 2回目に上書きされて実行されない }; window.onload = function () { console.log( 'window.onload 2回目' ); }; |
まとめ
今まで試した内容だとloadを使用するのが無難な感じになりますが、実行タイミングとしては、(1)直ぐに実行、(2)DOMContentLoaded、(3)load の順番になります。
1 2 3 4 5 6 7 | window.addEventListener( 'load' , function () { console.log( 'load' ); // 3番目 }); document.addEventListener( 'DOMContentLoaded' , function () { console.log( 'DOMContentLoaded' ); // 2番目 }); console.log( '直ぐに実行' ); // 1番目 |
例えばページのローディングを非表示にするタイミングであればloadで全てのリソース読み込み後になると思いますが、リソースの関わらないDOMの操作などであればDOMContentLoadedのタイミングで実行した方が早く処理が実行できますし、最初に試したユーザーエージェントの取得などであれば直ぐに実行しておいた方がよい場合が多いです。
このように、処理内容に応じてそれぞれを使い分けられるようにできるとよいのかなと思います。
コメントが承認されるまで時間がかかります。