アコーディオンの開閉とか、タブの切り替えとか、なにかと使用するjQueryのclickイベント。そんなclickイベント、いつも通り書いているはずなのに、2回クリックされたような動作になってしまうことがあります。 slideToggle で勝手に開閉してしまったり、toggleClass が効かなかったり。そんな時に確認すべきことを書いていきます。
例1.画面のリサイズ時にonを指定している場合
ひとつめの例は画面がリサイズされた時にクリックイベントを設定するような場面で起こる事象でした。clickイベントが繰り返し実行されてしまう記述がこちら。
$(function(){ $(window).on('load resize', function(){ var w = $(window).width(); var x = 767; if (w <= x) { $('.accordion').on('click',function () { $(this).find('.list').slideToggle(); }); } }); });
レスポンシブ対応のために、767px以下であれば「.accordion」をクリックした時にアコーディオンメニューを「slideToggle」で開閉する、という想定ですが、このままだとブラウザをリサイズする度に「on」の処理が積み重なり、1回のクリックで複数回実行されてしまうことになります。
例1.解決:「off」を指定
「on」の処理の前に「off」の処理を入れておくことで、解決できます。
$(function(){ $(window).on('load resize', function(){ var w = $(window).width(); var x = 767; if (w <= x) { $('.accordion').off('click'); $('.accordion').on('click',function () { $(this).find('.list').slideToggle(); }); } }); });
例2.labelの中にinputを記述している場合
HTMLの記述で、label の中に input(チェックボックス)を記述することがありますが、このような記述の時に、 label に対してクリックイベントを指定すると、label と input がどちらもクリックされたと認識され、想定した動作にならないことがあります。まず、うまく動作しない記述例がこちら。
HTML
jQuery
$('label').on('click', function() { $(this).toggleClass('checked'); });
label をクリックした時に、「checked」というクラスが無ければ付与、あれば外す、という処理を「toggleClass」で指定していますが、このままだと2回クリックされたことになり、想定した動作になってくれません。
例2.解決:inputのクリックで処理するよう記述を変更
この問題は、「label をクリックした時」ではなく、「input をクリックした時」にセレクタや処理を書き換えることで解決できます。
jQuery
$('label input').on('click', function() { $(this).parent().toggleClass('checked'); });
以上、jQueryでclickイベントが繰り返し実行されてしまう時の解決法でした。