Javascriptの記述場所・読み込み方をいろいろな方法で試してみます。
コードそのものがきちんと書かれていても、記述する場所や順番が間違っていることでうまく動作しないことが多々あり、これは私が超初心者のとき迷いながら勉強する中で状況をより難しくする原因になっていました。
【OK】単純なコードは設置場所を選ばない
初級段階で出会う簡単なサンプルコードやHTML要素の取得を必要としないシンプルなコードは、<script>タグの記述場所を選ばないケースが多いです。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<script>
console.log('headerの中に書いたJavascript');
</script>
</head>
<body>
<script>
console.log('bodyの中に書いたJavascript');
</script>
<script src="sample_07.js"></script>
</body>
</html>
↓ sample_07.jsの内容
console.log('外部ファイルで読み込んだJavascript');※実行結果を開いたブラウザについている「JavaScriptコンソール」でログを見ると、「headの中に書いたJavascript」「bodyの中に書いたJavascript」「外部ファイルで読み込んだJavascript」の上から順に読み込まれたことが分かります。
ですが、実務の場でWebページの表示速度を気にするようになったり、コードにDOMの操作(HTML要素の取得や生成)をするような複雑さが加わってくると、Javascriptの記述場所によっては不都合なことも起こります。
昔の初級者向けのテキストによく書かれていた「<head>タグの間に記述する」というのが最近では意外と使えなかったりします。
そのようなわけで、Javascriptの記述場所・読み込み方をいろいろな方法で試してみます。
【OK】<script>を</body>の直前に記述する
Webページがブラウザに表示される前の読み込みには順番があり、まずHTMLが読み込まれて、次にCSSや画像などの読み込みが行われ、そのあとにJavaScriptの読み込み・実行が行われます。
HTMLがすべて読み込まれる前にJavaScriptに遭遇すると、アクセスしたい要素が見つからないために実行できないJavaScriptが、再読み込みを繰り返すなどでページ全体の読み込み時間が遅くなる場合があります。
</body>の直前付近では、HTMLのデータがおおむね全部読み込まれているので、この位置にJavaScriptを記述することはページの表示速度の最適化に貢献します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
</head>
<body>
<div class="container">
<!-- ここに追加される -->
<p>Lorem ipsum ...</p>
<p>Lorem ipsum ...</p>
</div>
<script>
const StartTime = performance.now(); // 処理開始
const container = document.querySelector(".container");
const newBrock = '<h1 class="brock">Hello World!</h1>';
container.insertAdjacentHTML('afterbegin', newBrock);
const EndTime = performance.now(); // 処理終了
console.log( '処理にかかった時間は ' + (EndTime - StartTime) / 100 + ' 秒です' ); // 何ミリ秒かかったかを表示する
</script>
</body>
</html>
※ブラウザについている「JavaScriptコンソール」を開いてログを見ると、表示されるまでに掛かった処理時間を見ることができます。
【OK】
外部ファイルを</body>の直前で読み込む
先程とほぼ同じ内容のコードで<script></script>の中に記述されていた部分を、外部ファイルにしてリンクさせました。
こちらも</body>の直前付近に記述した場合は、HTMLのデータがおおむね全部読み込まれているので問題なく表示でき、ページの表示速度の最適化に貢献します。
※外部ファイルを読み込む場合も、対象のエレメントよりも前の位置に記述した場合は、アクセスしたい要素が見つからずエラーになります。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
</head>
<body>
<div class="container">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<script src="https://lab.hanjoy.site/sample/2025/05/12/sample_03.js"></script>
</body>
</html>
↓ sample_03.jsの内容
const StartTime = performance.now(); // 処理開始
const container = document.querySelector(".container");
const newBrock = '<h1 class="brock">Hello World!</h1>';
container.insertAdjacentHTML('afterbegin', newBrock);
const EndTime = performance.now(); // 処理終了
console.log( '処理にかかった時間は ' + (EndTime - StartTime) / 100 + ' 秒です' ); // 何ミリ秒かかったかを表示する
【NG】対象のエレメントよりも前に記述する
先程とほぼ同じ内容のコードですが、class=”container” が読み込まれるよりも前にJavascriptが書かれているためエラーが出てしまいました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
</head>
<body>
<script>
const StartTime = performance.now(); // 処理開始
const container = document.querySelector(".container");
const newBrock = '<h1 class="brock">Hello World!</h1>';
container.insertAdjacentHTML('afterbegin', newBrock);
const EndTime = performance.now(); // 処理終了
console.log( '処理にかかった時間は ' + (EndTime - StartTime) / 100 + ' 秒です' ); // 何ミリ秒かかったかを表示する
</script>
<div class="container">
<p>Lorem ipsum ...</p>
<p>Lorem ipsum ...</p>
</div>
</body>
</html>
※ブラウザの「JavaScriptコンソール」を開いてログを見ると、「Cannot read properties of null (reading ‘insertAdjacentHTML’) →insertAdjacentHTMLがアクセスしたい要素が存在しない」のエラーが出ます。
【場合によりNG】onload()イベントを使用して対象のエレメントよりも前に記述する
先程とほぼ同じ内容を window.onload()関数に代入することで「HTMLと画像やCSSなどのリソースの読み込みがすべて完了した後で」Javascriptの読込を始めることができるので、対象のエレメント(class=”container” )よりも前の位置に記述してもエラーにならずに実行が行われます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
</head>
<body>
<script>
window.onload = function() {
const StartTime = performance.now(); // 処理開始
const container = document.querySelector(".container");
const newBrock = '<h1 class="brock">Hello World!</h1>';
container.insertAdjacentHTML('afterbegin', newBrock);
const EndTime = performance.now(); // 処理終了
console.log( '処理にかかった時間は ' + (EndTime - StartTime) / 100 + ' 秒です' ); // 何ミリ秒かかったかを表示する
}
</script>
<div class="container">
<p>Lorem ipsum ...</p>
<p>Lorem ipsum ...</p>
</div>
</body>
</html>
【NG】onload()イベントを複数使用するとひとつしか実行されない
3つ並べていますが実際に読み込まれるのは一番最後の「3番」のみです。※ブラウザの「JavaScriptコンソール」のログに1と2が読み込めないエラーは表示されません。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
</head>
<body>
<script>
window.onload = function() {
const container = document.querySelector(".container");
const newBrock = '<h1 class="brock">1.Hello World!</h1>';
container.insertAdjacentHTML('afterbegin', newBrock);
}
window.onload = function() {
const container = document.querySelector(".container");
const newBrock = '<h1 class="brock">2.Hello World!</h1>';
container.insertAdjacentHTML('afterbegin', newBrock);
}
window.onload = function() {
const container = document.querySelector(".container");
const newBrock = '<h1 class="brock">3.Hello World!</h1>';
container.insertAdjacentHTML('afterbegin', newBrock);
}
</script>
<div class="container">
<p>Lorem ipsum ...</p>
<p>Lorem ipsum ...</p>
</div>
</body>
</html>
【OK】addEventListener()を使用して複数のスクリプトを実行する
addEventListener()のイベントタイプ:loadを使用すると、上記のonload()でできなかった複数の実行が可能になります。
※読み込まれる順番は1番からなので、実行結果では「3・2・1」と並んでいるのが分かります。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
</head>
<body>
<script>
window.addEventListener('load', function() {
const container = document.querySelector(".container");
const newBrock = '<h1 class="brock">1.Hello World!</h1>';
container.insertAdjacentHTML('afterbegin', newBrock);
})
window.addEventListener('load', function() {
const container = document.querySelector(".container");
const newBrock = '<h1 class="brock">2.Hello World!</h1>';
container.insertAdjacentHTML('afterbegin', newBrock);
})
window.addEventListener('load', function() {
const container = document.querySelector(".container");
const newBrock = '<h1 class="brock">3.Hello World!</h1>';
container.insertAdjacentHTML('afterbegin', newBrock);
})
</script>
<div class="container">
<p>Lorem ipsum ...</p>
<p>Lorem ipsum ...</p>
</div>
</body>
</html>
いろいろ試した結果、<script>に直接書き込む場合も、外部ファイルを読み込む場合も、</body>の直前に記述する方式が最も安定していると思いました。
