HTML
JavaScript

Javascriptはscriptタグを読み込んだ時点ですぐ実行される

エラーが出る例

ov01.html
<!DOCTYPE html>
<html>

<head>
  <script src="./ov01.js"></script>
</head>

<body>
  <button>ボタン</button>
</body>

</html>
ov01.js
var button1 = document.querySelector('button');

button1.addEventListener('click', function () { 
  return console.log('Clicked!');
});

何故エラーが出るかというと、<script src="./ov01.js"></script>が読み込まれた時点では、

ov01.html
<!DOCTYPE html>
<html>

<head>
  <script src="./ov01.js"></script>

までしか読み込まれてないからですね。

この時点でこのJavascriptを実行して

var button1 = document.querySelector('button');

とか言われても、buttonなんて要素はどこにもないから、querySelectorが無を返すわけですね。

エラーが出ない例

ov01.html
<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <button>ボタン</button>
  <script src="./ov01.js"></script>
</body>

</html>
ov01.js
var button1 = document.querySelector('button');

button1.addEventListener('click', function () { 
  return console.log('Clicked!');
});

<script src="./ov01.js"></script><button>ボタン</button>より後ろに配置してやれば、ちゃんと動きます。

余談

いや、多分、めちゃくちゃ基本的なことなんですよこれ。

にもかかわらず、今更ハマって「あれ??」ってなったんですよね。

多分、これまでjQueryとか書く時に

$(function(){
    // 実行内容
});

って何にも気にせずに書いてたから、問題にならなかったんでしょうね。

この書き方なら、htmlの読み込みが終わってから処理が実行されますからね。

でも、言われてみれば、jQueryライブラリ自体を読み込むscriptタグは先に書いてたなあ。

普段意識してないと、後から「そういえば。」ってなることが結構ありますね。

参考リンク

超シンプルなことしか書いてないこの記事より、詳しいことが知れます。

mozillaによる一次ソース。一番確実。
https://developer.mozilla.org/ja/docs/Web/HTML/Element/script#Notes

複数の外部JSファイルを読み込む時の実行順序について
http://analogic.jp/external-js-execute-timing/

【JavaScript基礎】JavaScriptの実行順序について
http://kde.hateblo.jp/entry/2017/05/20/212928