JavaScript でコードの記述によって実行タイミングが違うので HTML 要素が取得できない場合があります。
仕事中にちょっとハマってしまったのでメモ。
自分でまとめないと忘れると思うので。
冷静になればすぐわかることなんですがね…。
確認したこと
具体的な内容は以下のタイミングで取得できるかどうかです。
- JavaScript 読み込み時
- $(document).ready()
- window.onload()
これらを取得する要素の前後で実行します。
コード
HTML
jQuery をロードして<div>
の前後に before.js と after.js を記述。
<!DOCTYPE html> <html> <head> </head> <body> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script src="./before.js"></script> <div id="test"></div> <script src="./after.js"></script> </body> </html>
JS
before.js と after.js の内容。
before.js 出力はconsole.log('before XXXX : ' + $('#test')[0]);
にしています。
console.log('after init : ' + $('#test')[0]); $(window).on('after load', onload); $(function() { console.log('after ready : ' + $('#test')[0]); }); function onload() { console.log('after onload : ' + $('#test')[0]); }
結果
IE11 で確認。 この程度はブラウザに依る差異はないと思います。
before init のみ取得できませんでした。
なぜこうなるのか
init は JavaScript のロード時に実行されます。
before init は取得する要素が DOM にロードされる前に実行され、 after init は取得する要素が DOM にロードされた後に実行されます。
before init では DOM にロードされる前に要素を取得しようとしたため undefined になります。
ready は HTML のロード後、load はすべてのコンテンツのロード後に実行されるため、取得できます。 また、上書きではなくスタックされていくので before も after も実行されます。
まとめ
JavaScript は body の最後に記述しよう!!