13. デバッグとエラー解決

この章では、JavaScriptのデバッグとエラー解決を学びます。

JavaScriptを書いていると、必ずエラーに出会います。ボタンを押しても動かない、Consoleに赤いエラーが出る、本番だけ動かない、スマホだけ崩れる。実務ではこうした問題を自分で調べる力が必要です。

大切なのは、エラーを怖がらないことです。エラーは、ブラウザが「ここで何か問題が起きています」と教えてくれている情報です。

Consoleを見る

JavaScriptが動かない時、まず見るのはConsoleです。

Consoleには、エラー、警告、console.logの出力などが表示されます。

console.log
console.log("ここまで実行されました");

ボタンをクリックした時に処理が動いているか確認したい場合にも使えます。

クリック確認
button.addEventListener("click", () => {
    console.log("ボタンがクリックされました");
});

エラー文を読む

エラー文は英語ですが、よく出るものは限られています。

最初は全部理解できなくても、重要な単語を見るだけで原因を絞れます。

エラー例
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')

このエラーは、「nullに対してaddEventListenerを読もうとした」という意味です。

多くの場合、要素が取得できていません。

原因になりやすいコード
const button = document.querySelector(".js-button");

button.addEventListener("click", () => {
    console.log("クリック");
});

対象要素がないページで実行すると、buttonnullになります。

修正例
const button = document.querySelector(".js-button");

if (button) {
    button.addEventListener("click", () => {
        console.log("クリック");
    });
}

Cannot read properties of null

Web制作で非常によく見るエラーです。

エラー
Cannot read properties of null

主な原因は、対象要素が取得できていないことです。

確認することは次の通りです。

console.logで取得結果を確認します。

取得結果を確認する
const button = document.querySelector(".js-button");

console.log(button);

nullなら取得できていません。

is not a function

エラー
xxx is not a function

これは、関数ではないものを関数のように呼び出した時に出ます。

原因例
const button = document.querySelector(".js-button");

button.addEventlistener("click", () => {
    console.log("クリック");
});

この例では、addEventListenerLが小文字になっています。

正しくは次の通りです。

修正例
button.addEventListener("click", () => {
    console.log("クリック");
});

JavaScriptは大文字小文字を区別します。

Unexpected token

エラー
Unexpected token

これは、構文が壊れている時によく出ます。

原因例
if (button) {
    button.addEventListener("click", () => {
        console.log("クリック");
    });
// 閉じカッコが足りない

カッコ、波カッコ、クォート、カンマなどの不足を確認します。

エディタの整形機能や構文ハイライトを使うと気づきやすくなります。

変数の中身を見る

処理が思った通りに動かない時は、変数の中身を確認します。

変数を見る
const isOpen = button.getAttribute("aria-expanded") === "true";

console.log(isOpen);

複数の値をまとめて見たい時は、オブジェクトで出すと読みやすいです。

まとめて確認する
console.log({
    button,
    panel,
    isOpen,
});

確認が終わったら、不要なconsole.logは削除します。

処理の流れを見る

どこまで処理が進んでいるかわからない時は、目印を置きます。

処理の流れを確認する
console.log("1: 初期化開始");

const button = document.querySelector(".js-button");
console.log("2: button", button);

if (!button) {
    console.log("3: buttonがないので終了");
    return;
}

button.addEventListener("click", () => {
    console.log("4: クリックされた");
});

このようにすると、どこで止まっているかが見えます。

Elementsタブを見る

Elementsタブでは、現在のHTMLとCSSの状態を確認できます。

JavaScriptでクラスや属性を切り替えるUIでは、Elementsタブがとても役に立ちます。

確認することは次の通りです。

たとえば、ボタンをクリックしてもメニューが見えない場合、JavaScriptが動いていないのか、CSSで隠れたままなのかを切り分けます。

Networkタブを見る

Networkタブでは、ファイルが正しく読み込まれているか確認できます。

JavaScriptファイル自体が読み込まれていない場合、当然コードは動きません。

確認することは次の通りです。

  • main.jsが読み込まれているか
  • 404になっていないか
  • キャッシュされた古いファイルを読んでいないか
  • GSAPやSplideなどのライブラリが読み込まれているか
  • CSSファイルが読み込まれているか

breakpoints

DevToolsでは、コードの特定行で処理を一時停止できます。

これをbreakpointと呼びます。

クリックイベントの中で止めると、その時点の変数の中身を確認できます。

調べたいコード
button.addEventListener("click", () => {
    const isOpen = button.getAttribute("aria-expanded") === "true";

    button.setAttribute("aria-expanded", String(!isOpen));
});

breakpointを使うと、isOpentrueなのかfalseなのか、その場で見られます。

console.logだけでは追いにくい複雑な処理で役立ちます。

イベントが発火しているか確認する

クリックしても動かない時は、まずイベントが発火しているか確認します。

イベント確認
button.addEventListener("click", () => {
    console.log("クリックイベントは発火しています");
});

これが表示されない場合は、次を確認します。

  • 対象要素が取得できているか
  • イベントを付ける前にエラーで止まっていないか
  • 透明な要素が上に重なってクリックを邪魔していないか
  • pointer-events: noneになっていないか
  • 別の要素をクリックしていないか

イベントが発火しているのに見た目が変わらない場合は、DOM操作やCSS側を確認します。

本番だけ動かない時

ローカルでは動くのに、本番だけ動かないことがあります。

よくある原因は次の通りです。

まずはConsoleとNetworkを見ます。

エラーが出ていればエラー文と行番号、ファイルが読めていなければNetworkのステータスを確認します。

キャッシュを疑う

修正したのに反映されない時は、キャッシュが原因の場合があります。

確認方法の例です。

  • ブラウザをハードリロードする
  • DevToolsを開いた状態でキャッシュ無効化する
  • ファイル名にハッシュが付いているか確認する
  • サーバーやCDNのキャッシュを確認する

ただし、何でもキャッシュのせいにするのは危険です。

まずは、実際に読み込まれているファイルの中身や更新日時を確認しましょう。

スマホだけ動かない時

スマホだけ動かない場合は、次を確認します。

  • タッチ操作でイベントが発火しているか
  • 画面幅で条件分岐していないか
  • matchMediaの条件が正しいか
  • hover前提のUIになっていないか
  • メニューやモーダルのスクロール固定が効いているか
  • iOS Safari固有の挙動に引っかかっていないか

PCの幅を狭めただけでは再現できない問題もあります。

可能であれば実機でも確認しましょう。

質問・相談するときの情報

誰かに相談する時は、状況を具体的に伝えると解決が早くなります。

「動きません」だけだと、相手は原因を探せません。

エラー文と再現手順があるだけで、かなり調べやすくなります。

納品前チェック

納品前には、最低限次の項目を確認します。

  • Consoleに赤いエラーが出ていないか
  • 主要ページで共通JSのエラーが出ていないか
  • メニュー、モーダル、フォーム、スライダーが動くか
  • 複数設置したUIがそれぞれ独立して動くか
  • スマホ幅で操作できるか
  • キーボードで最低限操作できるか
  • NetworkでJavaScriptやCSSが404になっていないか
  • 不要なconsole.logが残っていないか

JavaScriptのエラーは、ユーザーには直接見えないこともあります。

しかし、裏でエラーが出ていると、別の処理が止まったり、ページ全体の操作に影響したりすることがあります。

よくある失敗

デバッグでよくある失敗を整理します。

  • Consoleを見ずにコードを何となく直し続ける
  • エラー文を読まずに検索だけする
  • どの行で止まっているか確認しない
  • 変数の中身を見ずに想像で直す
  • HTML側のクラス名違いに気づかない
  • Networkでファイル読み込みを確認しない
  • 本番で古いファイルを読んでいるのにコードだけ疑う
  • console.logを本番に残したままにする

デバッグは、勘で当てる作業ではありません。

事実を1つずつ確認して、原因を絞り込む作業です。

この章のまとめ

この章では、JavaScriptのデバッグとエラー解決を学びました。

  • 動かない時は、まずConsoleを見る
  • エラー文、ファイル名、行番号を確認する
  • Cannot read properties of nullは、要素取得失敗でよく起きる
  • console.logで変数の中身や処理の流れを確認する
  • Elementsでクラスや属性の変化を見る
  • NetworkでJavaScriptやライブラリの読み込みを確認する
  • breakpointsを使うと、処理を止めて状態を見られる
  • 本番だけ動かない時は、パス、キャッシュ、ビルド、HTML差分を確認する
  • 納品前にConsoleエラーを確認する習慣を持つ

これで、Web制作JavaScript完全講座の基本カリキュラムは一通り完了です。

ここから先は、各章のコードを実際に手を動かして書き、案件に近い小さなパーツを作りながら慣れていきましょう。