Javascript(jQuery)が動かない・反応しない
私は元々アプリケーションプログラマーでした。
アプリケーションのプログラムっていうのは基本的にはコンパイラ型言語という種類のプログラミン言語を使っており、プログラムをそのまま実行することは出来ず、コンパイラという変換器を使って実行ファイルに変換します。
このコンパイラ型言語の開発環境は、ソースコードを書く『エディタ』と、実行ファイルを作る『コンパイラ』と、エラーをチェックしてくれる『デバッガ』が一体となった統合開発環境というものになっいることが多く、デバッグが非常にしやすかったです。
しかし、最近では専らWEB系の仕事ばかりで、WEBではインタープリタ型言語という物で、ソースコードが実行アプリケーションにそのまま読み込まれて動作します。
WEB開発ではソースコードを書いて、サーバーにデプロイして、ブラウザのデバッガを使うことになるのですが、なんだか未だにやりにくいなぁって感じます。
Javascript(jQuery)が動かない
実際にサーバーにデプロイしても、Javascriptが動いてないってことありますよね。
原因を探すのも一苦労ですよ。
今回はjQueryの話ですが、jQueryが動かない理由はいくつかあります。
- 外部ファイルにしたjavascript(jQuery)が読み込めていない。もしくはファイルのパスが間違っている。
- FTPツールのファイル更新条件(更新日が新しいとか、ファイルサイズが大きいとか)が間違っていて、サーバーにファイルがアップロード出来ていなかった。
- 要素セレクタが間違っていて、イベントが発火していない。
- javascriptによって生成された要素にイベントを設定していた。
- イベント自体は発火しているが、内部でエラーを起こしている。
- WordPressでは$ドルマークでエラーが出ることがある。
Javascript(jQuery)が動かない原因1
『ファイルが読み込めてない』もしくは『パスが間違っている』
Javascriptはコンパイル型言語ではないため、実行時にブラウザがコードを読み取って、解析して実行されます。
JavascriptはHTML内に記述することもできますが、HTMLとは別ファイルに分けられていることが多いため、読み込みの際、パス指定が間違っているなどで、読み込めていないことがあります。
ファイルの読み込みが出来ていなければ、当然Javascriptは動きません。
Javascriptが読み込まれているか調べる方法
Javascriptが読み込めているか確認する簡単な方法はalertやconsole.logを出す方法です。
// アラートを出す
alert('test.jsが読み込まれた!');
// コンソールログを出す
console.log('test.jsが読み込まれた!');
// 以下、本来の処理
$(function() {
var element = document.~~~~
});
Javascriptファイルの最初にアラートやログを出すコードを書いておけば、読み込んですぐにメッセージを出してくれるため、わかりやすいです。
それでもアラートが表示されない場合は、Javascriptファイルが正しく読み込まれていません。
ファイルのパスが間違っていないか確認してください。
Javascriptの最後にコードを入れない理由としては、もしJavascriptのコードにエラーがあった場合には、そこで処理が止まってしまうので、アラートが出ません。
ファイルが読み込まれていないのか、途中で処理が止まってしまっているのかがわからないのです。
Javascript(jQuery)が動かない原因2
『FTPツールのファイル更新条件が間違っている』
みなさんの使っているFTPはなんですか?
FTPツールを使っていると、アップロードの条件に「ファイルが新しければ上書きする」「ファイルサイズが大きければ上書きする」などの条件を設定して、上書きする必要のないファイルのアップロードをしないようにして、処理を高速化してくれます。
しかし、この機能が原因でファイルがアップロードされないことがあります。
スクリプトが間違っていて、秒で修正して再度アップロードした場合
もし、FTPの設定で『ファイルが新しければ上書き』を設定していたら、上書きがかからないことがあります。
サーバーにアップロードされたファイルと、秒で更新したファイルの最終更新時間が分まで同じ場合、FTPが更新が行われていないと判断することがあるためです。
スクリプトの一部を消して、整理して記述し直した場合
例えば、冗長な処理をまとめて消して、整理して記述し直してアップロードした時、FTPの設定が『ファイルサイズが大きければ上書き』になっている場合、整理したことで、コード量が減るため、上書きがかからないことがあります。
これらの問題を回避するために、サーバー上に修正する前のファイルがずっと表示される時は、一時的にすべて上書きをしてみてください。
Javascript(jQuery)が動かない原因3
『セレクタが間違っている』
ここからJavascriptの話なんですが、イベントが発火しない原因として最も多いのが、『セレクタが間違っている』です。
以下の例は私もうっかりやってしまうことがあるのですが・・・
<div class="accordion"></div>
$("accordion").on("click", function() {
~~~
});
クラスにイベントをつけなきゃいけないのですが、セレクタが$(“accordion”)になっており、正しくは$(“.accordion”)にしないといけません。
ピリオドが1つ抜けるだけで動かないのです。
<nav>
<ul class="menu">
<li><a class="menu-btn"></a></li>
</ul>
</nav>
$("nav > .menu > .menu-btn").on("click", function () {
~~~
});
これも動かないです。
子セレクタを使って、イベントが発生する場所を絞っているのですが、セレクタの指定が間違っています。
このミスはイベントを設定した後に、デザイン変更が発生した時に起きやすいですね。
子セレクタを使う時は、デザイン変更があっても崩されにくい最小ブロックから指定するようにしましょう。
上記の例ではメニューボタンのリストなので、外にラッパーが付くことがあっても、ulが解体されることはあまり多くないでしょうから、$(“ul.menu .menu-btn”)でも十分だと考えます。
Javascript(jQuery)が動かない原因4
『javascriptによって生成された要素にイベントを設定していた』
これは結構多くの人が陥りやすいポイントなのですが、jQueryを使って生成した要素(タグ)を通常のセレクタで指定してもイベントが発火しません。
少しサンプルを用意しました。
See the Pen jQueryによる要素追加とイベントの発火テスト by Uilou (@uilou754) on CodePen.
このサンプルには2種類のJavascriptが記述されています。
1つは色名が書かれたボタンをクリックすると、色名を知らせるメッセージボックスが出るスクリプト
// クリックされた要素の中身をalertで通知する
$(".color").on("click", function() {
alert($(this).html()+"がクリックされました。");
});
もう1つは『要素を追加する』ボタンを押すと、色名が書かれたボタンを追加するスクリプトです。
// 要素を追加する用の配列
var colors = ["white", "red", "green", "blue", "purple", "orange", "yellow", "magenta", "cyan", "black", "gray"];
// .color_listに新しい要素を追加(append)する
$(".add_btn").on("click", function() {
$(".color_list").append(`<li class="color">${colors[Math.round(Math.random() * colors.length)]}</li>`);
});
今回、決まった色ではなく、ランダムで色が出るように色名の配列をあらかじめ用意しておいて、その中の文字をランダムに取得して表示するようにしています。
さて、問題はあらかじめ用意された4つのボタンはクリックするとアラートが表示されるにも関わらず、後で生成されたボタンはクリックしても反応しない点です。
これはHTMLの動作が影響しています。
- ブラウザはサーバーからWEBサイトのデータを受け取ると、HTMLの解析を始めます。
- 解析されたHTMLはDOM(Document Object Model)に変換されます。
- 途中でjavascriptが出てくると、javascriptの解析を始めます。
jQueryの$(element)はjavascriptが解析された時点でのDOMで動くため、javascriptが解析された時点では、まだボタンが押されず、要素が追加されていないため、イベントが発火しないんです。
同じ理由で、HTMLが読み込まれるより先にjavascriptを動かしたときも、まだDOMが生成されていないので、動かないです。
WEBアプリの動作の仕組みは以下の記事を参照してください。
これを回避するには、指定方法を変えることです。
//===========================================
// clickイベントを拾う時
//===========================================
// これでは動かないので
$(".color").on("click", function() {
~~~
});
// documentでclickイベントを拾って、".color"に絞り込む手法
$(document).on("click", ".color", function() {
~~~
});
//===========================================
// 何か操作をする時
//===========================================
// これでは動かないので
$(".color").each(function(index) {
~~~
});
// documentから要素を検索する
$(document).find(".color").each(function(index) {
~~~
});
これで後から要素を追加するような操作を含んでいても正常に動作します。
Javascript(jQuery)が動かない原因5
『スクリプト内部でエラーが出ている』
そもそもコーディング時にシンタックスエターが出ている場合は動きません。
要するに、ただの打ち間違いですね。
こういう打ち間違いやコード上の矛盾を見つけるのに便利なツールがあります。
JSHint
https://jshint.com/
こういう画面が表示されます。
例えば、以下のように入力してみました。
わざとエラーが発生するように書いてみました。
・One Warning
・One undefined valiable(定義されていない変数)
未定義の変数が使用されている場合、発生行数と未定義の変数名を表示してくれます。
・One unused valiable(使用されていない変数)
使用されていない変数が原因でプログラムが停止することはありませんが、こういう無駄な要素も見つけてくれるようです。
Javascript(jQuery)が動かない原因6
『WordPressでjQueryを使う場合、ドルマークでエラーが出ることがある』
WordPressではjQueryの$(ドルマーク)がエラーを出すことがあります。
$(ドルマーク)をjQueryに書き換えると正常に動きます。
// これを
$('.next').on('click', function() {
$('.hero').appendTo('.hero > *:first-child');
});
// ↓
// こういう風に書き換える
jQuery('.next').on('click', function() {
jQuery('.hero').appendTo('.hero > *:first-child');
});
WordPressではこれで正常に動くようになります。
そもそもjQueryはJavascriptで、jQueryで使われる$(ドルマーク)がjQueryそのものっていう複雑な話はまた今度しましょう。
もしお困りごとがありましたら、お問い合わせフォームよりご相談ください。