【WEB制作】JavaScriptが動かないときの原因特定方法

JavaScript

この記事ではJavaScriptが動かないときの解決手順を、WEBサイト制作のスクールでコーディング講師をしているコーサク(@bouru_02)が解説していきます。

JavaScriptが思ったように動かないんだけど、こんなときはどうやって解決すればいいの?

コーサク
コーサク

JavaScriptの問題を解決するにはChromeのデベロッパーツールが役に立ちます。

詳しく解説していきますね!

「ハンバーガーメニューが開かない…」「スライダーが反応しない…」など、WEB制作をしているとJavaScriptが思ったように動かない場面に遭遇することがあると思います。

今回は、JavaScriptがうまく動かないときに役に立つ、

  • 動かない原因を特定する方法
  • Chromeのデベロッパーツールの使い方

など、私も実務で使っている方法や考え方を詳しく解説していきます。

結構なボリュームになっていますが、ここで紹介する手順は、JavaScriptがうまく動かないときに汎用的に使える手順なので一度じっくりと読んでいただければ幸いです。

これを身に着けることで、今後JavaScriptがうまく動かないときの解決速度が爆上がりすると思います。

初心者でもわかりやすいように画像や実例も使って解説しているので、ぜひご一読ください!

JavaScriptがうまく動かない場合の解決手順

JavaScriptがうまく動かないときは以下の手順で進めていきます。

  1. 原因として考えられる箇所を洗い出す
  2. 原因箇所を特定する
  3. 1,2を繰り返して原因箇所を絞り込む
  4. 修正方法を調べる
  5. 原因箇所を修正する

手順1:問題の原因として考えられる箇所を洗い出す

問題が発生したときは、いきなり調査し始めてはいけません。

まず、問題が発生しそうな箇所を洗い出します。

JavaScriptがうまく動かないときは以下のタイミングのどこかで問題が起こっているパターンが考えられます。

JavaScriptが動かない原因となりそうな箇所
  1. jsファイルの読み込み時(原因例:ファイルのパスが間違っている)
  2. イベントの発動時(原因例:セレクタの指定が間違っている)
  3. メソッドの実行時(原因例:引数が間違えている)

そして洗い出したものを1つずつ確認して、問題がない箇所を原因の候補から消していくことで原因箇所を絞り込んでいきます

原因箇所を絞り込んでいくことの重要性については、以下の記事をご覧ください。

手順2:原因箇所を限界まで絞り込む

問題がありそうな箇所を洗い出したら、それらの箇所を処理の上流から確認していくことで、どこまでがうまくいっていて(問題がなくて)どこからがうまくいっていないのかを特定していきます。

この「上流から確認していく」というのがポイントです。

というのも、例えばそもそもjsファイル自体がHTMLに読み込めていない場合などは、コードの間違えをいくら調べても問題は解決しないからです。

処理の上流から確認することで、問題ない箇所と問題がある箇所を切り分ける。

jsファイルの読み込みがうまくいっているかの確認方法

まずはそもそもJavaScriptのファイルが上手く読み込めているのかを確認します。

これはChromeのデベロッパーツールを使うことで確認できます。

jsファイルが読み込めているかの確認手順
  • 手順1
    Chromeで対象のページを開きデベロッパーツールを起動

    jsファイルが読み込まれているかを確認したいページをChromeで開き、Ctrl + Shift + i右クリック -> 「検証」からデベロッパーツールを開きます。

  • 手順2
    「ソース」タブを開き、目的のjsファイルが表示されるかを確認

    デベロッパーツールのタブから「ソース」を選択すると、「ページ」タブの中にそのページで読み込まれているファイルが一覧で表示されます。

    その中に対象のjsファイルが見つかればファイルの読み込みはうまくいっているということがわかります。

    script.jsが正常に読み込まれている場合
    script.jsが読み込まれていない場合

jsファイルが読み込まれていることを確認できたら、次に進みます。

読み込まれていなければ、HTMLのjsファイルの読み込みの記述に問題がある可能性が高いです。

パスやファイル名の間違えがないかを確認しましょう。

JavaScriptのコードの中身に問題がある場合の確認方法

jsファイルは読み込めているのにうまく動かない場合はコードの中身に問題がある可能性が高いです。

まずはコードの何行目に問題があるのかというところまで原因箇所を絞り込んでいきます。

実際に問題があるコードを例として手順を解説していきます。

Chromeのデベロッパーツールを使ったJavaScriptのデバッグ方法

例として、以下のようなモーダルウィンドウをJavaScriptで実装するとします。

各コースの画像をクリックすると、
モーダルウィンドウが表示されるようにしたい
<div class="course-item">
    <a href=""><img src="./img/web_first.png" alt=""></a>
    <p>HTML/CSS/Bootstrap</p>
</div>
<div class="course-item">
    <a href=""><img src="./img/web_second.png" alt=""></a>
    <p>HTML/CSS/JavaScript/jQuery</p>
</div>
<div class="course-item">
    <a href=""><img src="./img/web_third.png" alt=""></a>
    <p>PHP/WordPress</p>
</div>

<!-- モーダルウィンドウの中身 -->
<div class="modal">
    <div class="bigImg"><img src="" alt=""></div>
    <p class="close-btn"><a href="">✖️</a></p>
</div>
$('course-item a').click(function () {
    /*  クリックした画像の子要素(img)のsrc属性をimgSrcの変数に設定する  */
    var ingSrc = $(this).children().attr('src');
    /*  bigImg内の子要素(img)のsrc属性を、imgSrcに書き換え  */
    $('.bigImg').children().attr('src', imgSrc);
    /*  fadeInで画像を表示  */
    $('.modal').fadeIn();
    /*  画面の縦スクロールをさせない処理  */
    $('body,html').css('overflow-y', 'hidden');
    /*  aタグの遷移を無効化する  */
    return false
});

// モーダルウィンドウを閉じる処理は省略

このモーダルウィンドウが、画像をクリックしても開かない場合の原因の特定から解決までの手順を見ていきましょう。※前提として、jsファイルの読み込みはうまくいっていることは確認済みとします。

エラーが出ていないかを確認する

まずはどこかでエラーが起きていないかをChromeのデベロッパーツールを使って確認していきます。

JavaScriptはコード内にエラーがある場合、エラーが発生したタイミングで処理が止まってしまいそれ以降の処理は実行されません

この仕様によって、モーダルウィンドウとは関係ないコードでエラーがあるせいでモーダルウィンドウが動いていない可能性もあります。

エラーが出ていないかの確認手順
  • 手順1
    Chromeで対象のページを開きデベロッパーツールを起動

    Ctrl + Shift + i右クリック -> 「検証」からデベロッパーツールを開きます。

  • 手順2
    「コンソール」タブにエラーが出ているかを確認

    デベロッパーツールの「コンソール」タブにはそのページで発生しているエラー一覧が表示されます。

    script.jsの2行目でエラーが起こっているようだ

    ここにエラーが出ている場合は手順3に進みましょう。

    エラーが特に出ていない場合エラーが原因ではないので、「ブレークポイントを設定してコードが期待した通りに動くかを確認する」まで進みましょう。

  • 手順3
    「ソース」タブでエラー箇所を確認

    エラーメッセージにはどのファイルの何行目でエラーが発生したかの情報も書いてあります。

    例えば手順2のエラーメッセージには「at script.js:2:1」と書いてあり、これは「script.jsの2行目にエラーがある」という意味です。

    「ソース」タブから該当箇所を確認するとエラーが出ている行に波線と×印が出ていることがわかります。

    2行目にエラーが出ている
  • 手順4
    エラーメッセージを確認

    ×印にマウスカーソルを合わせると、エラーメッセージが表示されます。

    このメッセージにはエラーの原因が書いてあるので、これを読むことで何が間違えているのかのヒントとなります。

    「$が定義されていない」ことが原因のエラーらしい

    エラーメッセージを読んでも意味が分からない場合は、エラーメッセージを丸ごと検索してみましょう。

    そのエラーを解説している記事が見つかることが多いです。

  • 手順5
    エラー原因を修正する

    エラーメッセージを解読したら、その原因となっている部分を修正します。

    今回の例では、エラーメッセージを調べてみたところ「jQueryで読み込まれてない段階でjQuery関数を使おうとしている場合に発生するエラー」ということで、jQueryの読み込み部分に問題がありました。

    jQuery読み込みの記述がコメントアウトされていたことが原因だった

ブレークポイントを設定してコードが期待した通りに動くかを確認する

jsファイルも正常に読み込めていてエラーも出ていないのにうまく動かない場合も多々あります。

そんなときは、JavaScriptのコードがどこまで正常に動いているのかを確認しましょう。

Chromeのデベロッパーツールでは、JavaScriptのコード中にブレークポイントを設定することで任意の行で処理を止めることができます。

ブレークポイントとは、コンピュータプログラムを実行する際に、開発者の指示で強制的に実行を一旦停止する箇所のこと。プログラムの開発時に設定されるもので、実行中のプログラムの状態を確認し、不具合の原因などを探るために用いられる。

https://e-words.jp/w/ブレークポイント.html

この機能を使ってコードがどこまでうまく動いているのかを確かめ、問題が起きている行を特定していきます。

ブレークポイントを使った原因箇所特定方法

ブレークポイントを設定した行は、その行を実行される前に処理が止まるという仕組みになっています。
これを利用すると、ある行が想定通り実行されているかを確認したい場合に役に立ちます

つまり、ある行のコードが想定通り実行されるかを確認するには、その次の行にブレークポイントを設定し、そのコードが実行されるはずの操作(ボタンのクリックやフォームへの入力など)をして、きちんと処理が止まるかを確認すればよいというわけです。

では、具体的な手順の解説です。

ブレークポイントを使った原因箇所特定方法
  • 手順1
    Chromeで対象のページを開きデベロッパーツールを起動

    Ctrl + Shift + i右クリック -> 「検証」からデベロッパーツールを開きます。

  • 手順2
    「ソース」タブの確認したい行にブレークポイントを設定

    「ソース」タブを開きコードの行数部分をクリックすることで、その行にブレークポイントが設定されます。

    ブレイクポイントは複数設定できる
  • 手順3
    ブレークポイントを設定した行で処理が止まるかを確認

    ブレークポイントを設定すると、設定した行の処理が実行される直前で処理が止まります。

    例えば手順2では3行目と5行目にブレークポイントを設定しています。

    3行目のブレークポイントは3行目の直前で処理が止まるので、2行目の

    $(function() {

    というjQueryの読み込み直後に処理が止まるはずです。

    ということはこのブレークポイントで処理が止まることを確認するにはjQueryの読み込みを実行させればよいということです。

    jQueryの読み込みはページ読み込み時に実行されるので、ページをリロードすると、3行目のブレークポイントで処理が止まることが確認できます。

    3行目のブレークポイントは正常に処理が止まることが確認できた
  • 手順4
    ブレークポイントが期待した通りに動かない箇所を探す

    手順3のように期待したタイミングで処理が止まるブレークポイントと、逆に期待したタイミングで処理が止まらないブレークポイントを確認することで、問題があるコードを特定できます。

    この説明だけではわかりにくいので、詳しく解説しますね。

    例えば手順2の5行目のブレークポイントの処理が止まるのは5行目の処理の直前、つまり3行目の

    $('course-item a').click(function() {

    の実行直後となります。※4行目のコメントはコードではないため無視されます。

    3行目のコードが実行されるのはcourse-item aがクリックされたときなので、問題がなければcourse-item aをクリックした際に処理が止まることが期待されます。

    「.course-item a」は画像のハイライト部分

    しかし、実際に該当箇所をクリックしても5行目のブレークポイントでは処理が止まりませんでした

    正常にコードが動いていれば処理が止まるはずなので、5行目の直前までに何か問題が起きているということがわかります。

    そして手順3で2行目までは正常にブレークポイントが動作していることが確認できているので、2行目以降で5行目の直前、つまり3行目の処理がうまくいっていないのではないかというところまで原因箇所が絞れます。

    3行目の処理がうまくいっていないようだ
  • 手順5
    原因箇所を修正する

    問題が起きている箇所を特定出来たら、後はそれを修正します。

    今回の例で問題の行は以下のようなコードになっています。

    $('course-item a').click(function() {

    このコードの次の行のブレークポイントが動かない、かつエラーも特に出ていないということは、.course-item aがクリックされたということが検知されていないのではないか?という仮説が立てられます。

    HTMLとJavaScriptを見比べると、JavaScriptのセレクタが$('course-item a')となっておりこれが間違いだとわかりました。(正しくは$('.course-item a')

    <div class="course-item">
        <a href=""><img src="./img/web_first.png" alt=""></a>
        <p>HTML/CSS/Bootstrap</p>
    </div>

原因箇所を1行からさらに絞り込む方法

ブレークポイントを利用して問題のある行を見つけても、なにが原因かがわかりにくいことがあります。

例えば今回の例で使っているモーダルウィンドウのコードは、ここまでの修正をしてもまだ以下のコードで問題が起こっているようです。

$('.bigImg').children().attr('src', imgSrc);

行が特定できてもその中のどこに問題があるかがわからない場合は、行の中身を分割してさらに絞り込んでいく必要があります。

まずは1行の中身を分割してみましょう。セレクタやメソッドのかたまり毎に以下のようにわけられそうです。

  • $('.bigImg')
  • children()
  • attr('src', imgSrc)

1行をセレクタやメソッドのかたまり毎に分割できたら、次はそれぞれのどこに問題があってどこが問題ないのかを確認することで原因箇所を絞り込んでいきます。

分割した箇所をそれぞれ書き換えてみる

セレクタやメソッドなど、行のどこかの箇所に問題があって動かないということは言い換えると以下のようになります。

ある箇所を消して問題なく動くようになれば、消した箇所に問題があって他の箇所には問題がないといえる。

この考え方を利用して問題ない箇所を見つけることで原因箇所を絞り込んでいきます。

実際には単純にコードを消すとエラーが出てしまうので、消すのではなくコードを書き換えることにします。

まずは$('.bigImg')というセレクタの指定に問題がないのかを確かめてみましょう。

children()attr('src', imgSrc)を消して(書き換えて)うまく動けば問題がないといえますね。

以下のようにシンプルに書き換えてみました。

$('.bigImg').addClass('hoge');

そしてこれが動くかを確認すると、以下のように正常に動作することが確認できました。

次の行にブレークポイントを設定しクリックイベントを発生させる
「要素」タブでhogeクラスが付与されていることを確認

ということで、$('.bigImg')の部分には問題がなさそうです。

次はchildren()が問題なく動くのかを確かめてみます。

$('.bigImg')の部分には問題がないので、$('.bigImg').children()はそのまま使ってattr('src', imgSrc)の部分を書き換えます。

$('.bigImg').children().addClass('hoge');

これが動くかを確認したところ、こちらも以下のように正常に動作することが確認できました。

.bigImgの子要素にhogeクラスが付与されていることを確認

ということで、問題はattr('src', imgSrc)の部分にありそうです。

ここまで来たら、attrメソッドの使い方を調べてみましょう。

ググるのは原因を極限まで絞り込んでから

まず、メソッド名につづり間違えなどの凡ミスがないかを確認しましょう。問題なさそうですね。

メソッドの使い方を調べてみると、.attr([属性], [値])というように引数を渡すことで、第一引数で指定した属性に第二引数の値を設定するメソッドのようです。

では、attr('src', imgSrc)をさらに分割して、原因箇所をさらに絞り込んでいきます。

第一引数のsrcと第二引数のimgSrcに分割できそうです。

まずは第一引数に問題がないかを確認します。

今までと同様にsrc以外の未確認の箇所を変えて正常に動くことが確認できればよいので、第二引数のみをシンプルなものに変更してみます。(この行の他の箇所は問題ないことをすでに確認済みのため)

変数ではなく、適当な画像のパスを直接文字列で指定してみます。

$('.bigImg').children().attr('src', './img/web_first.png');

すると、指定した通りの画像が表示されました。

imgタグのsrc属性に指定した画像パスが入っていることが確認できた

これによって、原因箇所はimgSrcにあるというところまで絞れました。(本当はsrcだけを変えてimgSrcがうまく動かないことも確認したほうがよいです。)

では、変数imgSrcのどこがおかしいのかを確認していきましょう。

JavaScriptがうまく動かない原因が変数の場合、変数の中身が想定していないものになっている可能性が高いです。

ブレークポイントを設定して変数を確認する方法

ある時点での変数の中身を確認したいときにも、ブレークポイントが役に立ちます。

ブレークポイントで一時停止をした際に、変数の上にマウスカーソルをあてると一時停止をした時点での変数の値が確認できます。

変数ingSrcには文字列型の「./img/web_first.png」という値が入っている

また、一時停止をしたまま「コンソール」タブに変数名を打ち込むことでも変数の中身を確認できます。

変数ingSrcには文字列型の「./img/web_first.png」という値が入っている

この方法を使ってimgSrcの値を見てみると、「ソース」タブでカーソルを重ねても何も出てきません。

「コンソール」タブでも確認したところ、以下のようにエラーが出てきました。

変数imgSrcの中身を確認するとエラーが出る

ここでもエラーメッセージにヒントが隠されています。

読んでみると、imgSrc is not defined、つまり、「変数imgSrcは定義されていない」というエラーのようです。

どうやら変数imgSrcが未定義となっており値が取得できないことがJavaScriptがうまく動かない原因になっていたようです。

次は変数の出所を順番にさかのぼっていき、どこでおかしくなっているのかを確認していきます。

今回のimgSrcは1つ前の行で定義されているようなのでここを確認してみます。

var ingSrc = $(this).children().attr('src');
/*  bigImg内の子要素(img)のsrc属性を、imgSrcに書き換え  */
$('.bigImg').children().attr('src', imgSrc);

すると、変数名をimgSrcではなくingSrcと間違えていることが判明しました!

ということでこれを直したところ、無事モーダルウィンドウが動くようになりました。

ついに動いた!

なお、今回は問題のある変数をさかのぼってすぐに原因箇所が見つかりましたが、もっと遠いところでおかしくなっていることも多々あります。

そういうときも焦らず、ブレークポイントを使って少しずつ処理を止めながらどこまで正常に変数が受け渡されていてどこからおかしくなっているのかを確認してください。

問題解決のためには、どこまでいっても「問題のない箇所とある箇所を切り分けていくこと」が大事!

まとめ:検証ツールはとても便利なので使いこなそう

ということで、JavaScriptがうまく動かないときのデベロッパーツールを使った原因特定方法を解説してきました。

結局のところ問題を解決するための手順はシンプルで、

問題の原因となりうる範囲をいくつかに分け、その中で問題が起こっている範囲を特定、問題が起こっている範囲をいくつかに分ける。

ということの繰り返しです。

これはJavaScriptに限らず、CSSやWordPressなどWEB制作における他の技術にも応用できる考え方です。

また、今回紹介した以外にもデベロッパーツールには便利な機能がたくさんあるので、ぜひ色々と調べてみてください!

コメント

タイトルとURLをコピーしました