べんりワザ・つまずいたとき

「Cannot read properties of null (reading 'addEventListener')」の直し方

JavaScriptで要素を探したのに見つからず、nullに対してaddEventListenerを呼んだときに出るエラーです。原因は「scriptの位置」か「セレクタのまちがい」のどちらかがほとんど。見分け方と直し方をまとめました。

Consoleにこのエラーが出たら、JavaScriptが要素を探したけれど見つからなかったという意味です。

Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')

原因はほぼ次の2つのどちらかです。

  1. scriptが早すぎる:HTMLの要素ができる前にJavaScriptが動いている
  2. 探し方がまちがっている:セレクタやidの綴りがHTMLと合っていない

どちらなのかは、1行確かめるだけで見分けられます。

エラー文の読み方

部分意味
TypeError値の種類がおかしい(ここでは「要素のはずがnullだった」)
Cannot read properties of nullnull(何もない)の中身を読もうとした
(reading 'addEventListener')読もうとしたのはaddEventListener

たとえばこう書いていたとします。

const btn = document.querySelector('.menu-button');
btn.addEventListener('click', () => { /* … */ });

querySelectorは、要素が見つからないときnullを返します。btnがnullなので、null.addEventListenerを呼ぶことになり、エラーになります。

どちらが原因か見分ける

エラーが出た行のすぐ前に、次の1行を足して再読み込みします。

console.log(document.querySelector('.menu-button'));

次に、ページの読みこみが終わったあと、Consoleに同じ1行を直接打って試します。

書いた場所でConsoleで打つと原因
null要素が出るscriptが早すぎる → 原因1へ
nullnull探し方がまちがっている → 原因2へ

原因1:scriptが早すぎる

ブラウザはHTMLを上から順に読みます。<head>の中でscriptを読みこむと、まだ<body>の中身ができていないうちにJavaScriptが動くので、要素が見つかりません。

<!-- ✕ bodyの中身ができる前に動く -->
<head>
  <script src="script.js"></script>
</head>

直し方は2通りあります。どちらか1つで大丈夫です。

deferを付ける(おすすめ)

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

deferを付けると、HTMLを最後まで読み終えてからscriptが動きます。<head>にまとめて書けるので、いまはこちらが主流です。

bodyの閉じタグの直前に置く

<body>
  …ページの中身…
  <script src="script.js"></script>
</body>

昔からある方法です。ページの中身を読んだあとにscriptが来るので、要素はもうできています。

原因2:探し方がまちがっている

Consoleで打ってもnullなら、その名前の要素がページにありません。よくあるまちがいはこのあたりです。

  • .と#のまちがい:class="menu-button"は'.menu-button'、id="menu-button"は'#menu-button'
  • getElementByIdに#を付けている:getElementById('#menu')ではなくgetElementById('menu')。#が要るのはquerySelectorのときだけです
  • 綴りや大文字小文字のちがい:menuButtonとmenubuttonは別の名前です
  • 別のページで動いている:全ページで同じscript.jsを読みこんでいて、そのボタンがないページでエラーになっている

最後のパターンは、「要素があるときだけ動かす」ように書けば解決します。

const btn = document.querySelector('.menu-button');
if (btn) {
  btn.addEventListener('click', () => { /* … */ });
}

短く書くなら、?.(オプショナルチェーン)も使えます。btnがnullのときは、何もせずに通り過ぎます。

btn?.addEventListener('click', () => { /* … */ });

まとめ

  1. このエラーは「要素が見つからず、nullに対して呼んだ」という意味
  2. 書いた場所ではnull、Consoleでは見つかる → scriptが早すぎる。deferを付けるか</body>の直前へ
  3. どこで打ってもnull → セレクタのまちがい。.と#、綴り、getElementByIdの#を確認
  4. 要素がないページもあるなら、ifで囲むか?.で呼ぶ
べんりワザエラーが出ても、あわてないほかのエラーメッセージの読み方はこちらにまとめています3べんりワザJavaScriptが動かないときの調べ方エラーが出ていないのに動かないときの調べ方はこちら

よくある質問

「Cannot read properties of null」とはどういう意味ですか?
null(何もない)の中身を読もうとした、という意味です。querySelectorやgetElementByIdで要素が見つからなかったときにnullが返り、そのnullに対してaddEventListenerなどを呼ぶとこのエラーになります。
scriptタグはどこに書けばいいですか?
headの中に書いてdeferを付けるか、閉じる </body> の直前に書きます。どちらもHTMLの読みこみが終わってからJavaScriptが動くので、要素が見つからないエラーを防げます。
Firefoxだとエラー文がちがいます
Firefoxでは「Uncaught TypeError: can't access property "addEventListener", btn is null」と表示されます。言い回しはちがいますが、意味も直し方もChromeと同じです。