JavaScriptを書いてブラウザで開いたのに、クリックしても何も起きない。
エラーらしきものも見当たらず、どこを直せばいいのかも分からない。
ボタン押しても無反応やねん…画面が静かすぎて、逆に怖いんやけど。
JavaScriptは、CSSと違って失敗した理由をブラウザが教えてくれる言語です。
その報告先がコンソールで、ここを開くだけで原因の大半は絞り込めます。
この記事では、切り分けの手順と8つの原因別の対処法を、初心者の方向けに順を追って解説します。
こんな人におすすめ
「JSが動かないが、何を見ればいいか分からない」
「コンソールの赤い文字を読み飛ばしている」
「動かないたびにコードを書き直して消耗している」
まず最初にやる3つの切り分け
原因を探す前に、処理がどこまで届いているかを確認します。
1. コンソールを開く
ページ上で右クリックして「検証」を選び、「Console」タブを開きます。
ショートカットなら、Windowsは F12、Macは Command + Option + I です。
赤い文字のエラーが出ていれば、そこがほぼ答えです。
読み方は原因①で詳しく解説します。
2. JSファイルが読み込まれているか見る
エラーが何も出ていない場合は、そもそもJavaScriptが実行されていない可能性があります。
検証ツールの「Network」タブを開いてページを再読み込みし、自分のJSファイルが読み込まれているか確認してください。
3. console.logで処理の到達点を調べる
ファイルの先頭と、動かない処理の直前に目印を置きます。
console.log('ファイルは読み込まれた');
const btn = document.querySelector('.btn');
console.log('取得した要素:', btn);
btn.addEventListener('click', function () {
console.log('クリックされた');
});JavaScriptどこまで表示されるかで、問題の場所が一気に絞れます。
| 状況 | 疑うところ |
|---|---|
| 1つ目も表示されない | ファイルが読み込まれていない(原因②) |
| 要素がnullと表示される | 取得の失敗かタイミング(原因③・④) |
| クリックしても最後が出ない | イベントの付け方(原因④・⑤) |
原因①:コンソールにエラーが出ている
エラーは英語で表示されますが、見るべき場所は3つだけです。
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
at main.js:5JavaScript- エラーの種類(TypeError などの部分)
- 内容(何がダメだったかの説明)
- ファイル名と行番号(main.js:5 の部分)
行番号をクリックすると、その行にジャンプできます。
よく出る3つのエラー
| エラー名 | 意味 | よくある原因 |
|---|---|---|
| SyntaxError | 文法が壊れている | 括弧やクォートの閉じ忘れ、全角文字の混入 |
| ReferenceError | 存在しない名前を呼んでいる | 関数名・変数名の綴り違い、読み込み順のミス |
| TypeError | 値の種類が想定と違う | 要素が取得できずnullのまま操作している |
とくに「Cannot read properties of null」は、初心者がもっとも遭遇するエラーです。
これは要素を取得できていないという意味なので、原因③か④を確認してください。
英語やから読まんと閉じてたけど、ヒントそのものやったんか…!
原因②:JSファイルが読み込めていない
コンソールに何も出ず、console.logの1行目すら表示されない場合はこれを疑います。
パスが間違っている
<script src="js/main.js"></script>HTMLNetworkタブで該当ファイルが404になっていれば、パスかファイル名が違っています。
- HTMLから見た相対パスになっているか
- ファイル名の綴りが合っているか
- 大文字と小文字が一致しているか(
Main.jsとmain.jsは別物)
scriptタグの書き方が崩れている
<script>は閉じタグを省略できません。
<!-- 正しい書き方 -->
<script src="js/main.js"></script>
<!-- 閉じていないので動かない -->
<script src="js/main.js">HTMLまた、srcで外部ファイルを読み込むタグの中に、直接コードを書いても実行されません。
外部ファイルの読み込みと直接記述は、タグを分けて書いてください。
原因③:要素が作られる前にスクリプトが動いている
HTMLは上から順に読み込まれるため、head内でJSを読み込むと、まだ存在しない要素を探しにいくことになります。
その結果、要素の取得結果がnullになり「Cannot read properties of null」が発生します。
対処1:deferを付ける
<script src="js/main.js" defer></script>HTMLdeferを付けると、HTMLをすべて読み込んだあとにスクリプトが実行されます。
head内に書いたままで解決できるため、現在はこの方法が扱いやすい選択肢です。
対処2:body の終了直前に書く
</body>の直前に<script>を置く方法も、昔からよく使われています。
対処3:読み込み完了を待ってから実行する
document.addEventListener('DOMContentLoaded', function () {
const btn = document.querySelector('.btn');
console.log(btn);
});JavaScript読み込みを待つ書き方は複数あるため、違いはこちらの記事にまとめています。

原因④:要素の取得に失敗している
タイミングは合っているのに要素が取れない場合、指定の書き方が間違っています。
取得できたかどうかは、console.logで中身を出せばすぐ分かります。
記号の付け方を間違えている
// querySelector は CSS と同じ書き方(記号が必要)
document.querySelector('.btn'); // class="btn"
document.querySelector('#btn'); // id="btn"
// getElementById は id 名だけ(記号は不要)
document.getElementById('btn'); // 正しい
document.getElementById('#btn'); // null になるJavaScriptgetElementByIdに「#」を付けてしまうミスは非常に多いので、まずここを確認してください。
複数の要素をまとめて扱おうとしている
querySelectorAllで取得したものは、要素そのものではなく要素のリストです。
const items = document.querySelectorAll('.item');
// これは動かない
items.addEventListener('click', fn);
// 1つずつ処理する
items.forEach(function (item) {
item.addEventListener('click', fn);
});JavaScriptまた、querySelectorは最初の1つしか取得しません。
「1つ目だけ動く」という症状なら、これが原因です。
要素の取得方法そのものを整理したい方は、こちらもあわせてどうぞ。

原因⑤:あとから追加した要素にイベントが付かない
イベントは、登録した時点で存在していた要素にしか付きません。
そのため、JavaScriptであとから追加した要素をクリックしても反応しません。
解決策は、常に存在している親要素にイベントを付ける方法です。
document.querySelector('.list').addEventListener('click', function (e) {
const item = e.target.closest('.item');
if (!item) return;
console.log('クリックされた項目:', item);
});JavaScript親でクリックを受け取り、押された場所が目的の要素かどうかを判定しています。
この書き方はイベント委任と呼ばれ、要素が増減するUIでは定番の手法です。
原因⑥:文法エラーで処理全体が止まっている
JavaScriptは文法エラーがあると、そのファイル全体が実行されません。
「昨日まで動いていた処理まで急に止まった」という場合は、これを疑ってください。
括弧やクォートの閉じ忘れ
// クォートが閉じていない
console.log('こんにちは);
// 波かっこが足りない
function greet() {
console.log('hello');JavaScriptコンソールにSyntaxErrorと行番号が出るので、その周辺を見れば見つかります。
ただしエラー行の少し手前に原因があることも多いため、前後を含めて確認しましょう。
全角文字が混ざっている
日本語入力のまま書いてしまい、全角のスペースやクォート、括弧が紛れ込むケースです。
エディタの表示では見分けづらいので、怪しい行は半角で打ち直すのが早い解決策です。
原因⑦:スペルミス・大文字小文字の違い
JavaScriptは大文字と小文字を厳密に区別します。
1文字違うだけで別のものとして扱われ、動作しません。
| 間違い | 正しい書き方 |
|---|---|
addEventListner | addEventListener(eが抜けやすい) |
getElementByID | getElementById(dは小文字) |
innerHtml | innerHTML(HTMLは大文字) |
lenght | length |
document.getElementsByClassNameの単数形 | Elementsと複数形になる点に注意 |
綴りが間違っていると、多くの場合TypeErrorやReferenceErrorとしてコンソールに表示されます。
エディタの入力補完を使って手打ちを減らすのが、もっとも確実な予防策です。
原因⑧:処理の結果を待たずに使っている
データの取得など時間のかかる処理は、結果が返る前に次の行へ進みます。
// 待っていないので、中身ではなくPromiseが表示される
const data = fetch('/api/data');
console.log(data);JavaScript「値がundefinedになる」「Promiseと表示される」といった症状は、これが原因です。
async function getData() {
const res = await fetch('/api/data');
const data = await res.json();
console.log(data);
}JavaScriptawaitの付け忘れはとくに多いので、非同期処理を書いたときは必ず確認しましょう。
ワイのundefined、ぜんぶこれやったかもしれん…。
それでも直らないときに見るところ
古いJSファイルが読み込まれている
ブラウザのキャッシュが残っていると、修正前のJSが実行され続けます。
Windowsは Ctrl + Shift + R、Macは Command + Shift + R でスーパーリロードを試してください。
ブラウザの拡張機能が邪魔をしている
広告ブロック系の拡張機能が、スクリプトの読み込みを止めてしまうことがあります。
シークレットウィンドウで開いて動くなら、拡張機能側の影響と判断できます。
WordPressでだけ動かない
WordPressでは、jQueryの「$」がそのままでは使えない設定になっています。
同じコードがローカルでは動くのにWordPress上でだけ動かない場合は、この点を確認してください。

編集しているファイルが違う
意外と多いのが、実際に読み込まれているのとは別のファイルを編集しているというケースです。
検証ツールの「Sources」タブでは、ブラウザが読み込んでいるコードそのものを見られます。
ここに自分の修正が反映されていなければ、ファイルの場所かビルドの設定を見直しましょう。
まとめ
JavaScriptが動かないときは、まずコンソールを開く。これに尽きます。
エラーが出ていれば、種類と行番号がそのまま原因のヒントになります。
エラーが出ていなければ、console.logで処理がどこまで届いているかを調べます。
そこから、読み込み・タイミング・要素の取得・綴りの順に見ていけば、原因までたどり着けます。
見た目が変わらない場合はCSS側の問題であることも多いので、あわせてこちらもどうぞ。

これからは、慌てる前にコンソール開くわ。ほな、また詰まったら来るで!
よくある質問
- エラーが何も出ないのに動きません。何を確認すればいいですか?
-
まずJSファイル自体が読み込まれているかを確認してください。ファイルの先頭にconsole.logを書いて表示されなければ、パスの間違いやscriptタグの書き方が原因です。
- 「Cannot read properties of null」とはどういう意味ですか?
-
要素を取得できていない(nullになっている)状態で、その要素を操作しようとしたという意味です。セレクタの書き間違いか、要素が作られる前にスクリプトが動いていることが原因です。
- scriptタグはheadとbodyのどちらに書くべきですか?
-
head内に書いてdefer属性を付けるのが扱いやすい方法です。body終了タグの直前に書く方法でも問題ありません。どちらもHTMLが読み込まれたあとに実行されるため、要素の取得に失敗しにくくなります。
- querySelectorとgetElementByIdはどちらを使えばいいですか?
-
CSSと同じ書き方で指定できるquerySelectorのほうが、覚えることが少なく扱いやすいです。ただしgetElementByIdはid名だけを書き、「#」を付けないという違いがあるため、混同しないよう注意してください。
- 1つ目の要素だけ動いて、2つ目以降が動きません。
-
querySelectorは条件に合う最初の1つしか取得しないためです。複数の要素に同じ処理を付けたい場合は、querySelectorAllで取得してforEachなどで1つずつイベントを登録してください。
- ローカルでは動くのに、WordPressに載せると動きません。
-
jQueryを使っている場合は「$」がそのまま使えない設定になっている点を確認してください。あわせて、テーマやプラグインが読み込むスクリプトとの競合、キャッシュ系プラグインが古いJSを配信していないかも確認しましょう。