ラボ > Javascript関連:イベント関連

jquery 複数のイベント設定で発火しない

イベント設定したけど発火してくれない・・・「return false」じゃなく「preventDefault()」を使ったほうが良さげ。イベントの伝播絡み。

作成日:2018-03-20, 更新日:2019-07-26

経緯

・他人が作った既存サイトを修正することに。
・「$(document).on('click', 'a', function(){alert('hoge');})」的な感じなイベント設定。
・aタグクリックしてもイベントが発火してくれない。

調べると・・・下記のようなのが他にいた。

$(〇〇〇).on('click', 'a[href^="#"]', function() {
  ~ なんかの処理 ~
  return false;
}

「return false」が問題になるらしい。
詳しくは・・・調べてもよく分からなかったので・・・要は「preventDefault()」をする必要があるそうだ。

ダメなサンプル

$(〇〇〇).on('click', 'a[href^="#"]', function() {
  ~ なんかの処理 ~
  
  return false;
}

$(〇〇〇).on('click', 'a', function() {
  // 上で設定したイベントのせいで、ココに入ってくれない。
}

・「return false」でリンク機能を無効にした結果、以降のリンクイベントが発火されない。

okなサンプル

$(〇〇〇).on('click', 'a[href^="#"]', function(e) {
  e.preventDefault(); // ←追加
  
  ~ なんかの処理 ~
  
  // return false; // ←コメント
}

$(〇〇〇).on('click', 'a', function() {
  // ココに入ってくれる。
}

・「e.preventDefault()」でイベントの伝播は許可して、ページ遷移を無効にする。

preventDefault()、stopPropagation()、return false

「e.preventDefault();」ってヤツは「イベントの伝播を止める」ってヤツ。
「イベントの伝播」ってのを「バブリング」というらしい。

内容 バブリング ページ遷移 詳細
preventDefault() 有効 無効 バブリングのみ有効
stopPropagation() 無効 有効 ページ遷移のみ有効
return false 無効 無効 バブリングもページ遷移も無効

「return false」は、そこで終了な感じだけど「preventDefault()」と「stopPropagation()」の位置は気にしなくて良さげ。
調べていると最初に設定している人が多いみたい。

$(〇〇〇).on('click', '〇〇〇', function(e) {
  e.preventDefault();
  ~ なんかの処理 ~
}

// ▼上記と同じ挙動。ひょっとしたら微妙に違うかも。
// $(〇〇〇).on('click', '〇〇〇', function(e) {
//   ~ なんかの処理 ~
//   e.preventDefault();
// }

サンプル

aタグクリックでform送信させる

ページ遷移先に値を渡すには色々と方法がある。

普通にform送信したり、aタグのリンク先にgetパラメータを付加したり・・・。
form送信もチェックボックスやラジオボタンで値を選択させたり、ボタンにname属性をつけて処理を割り振ったり、値を持たせたり・・・。

状況としては
・共通データとクリックされた値を送りたい。
・CSSの絡みがあるのでbuttonタグじゃなくaタグ希望
・POST送信させたい
・Javascriptの記述は少なくしたい
っていう感じ。

追加条件は下記。
・「radioボタン+送信ボタン」は2回クリックさせるからダメ。
・「radioボタン」をクリックで「form送信(submit())」させる記述でも良いけど、CSSが面倒だからダメ。
・formタグ無しで、クリック時に「form生成+追加+送信」ってのは、HTMLの修正時が面倒だからダメ。

・・・ということで、
・aタグに個別データとしてdata属性に値を付与。
・そのaタグクリック時にdata属性の値を付与したformデータを送信。
というコトにする。

<form method="post" action="〇〇〇">
  <input type="hidden" name="user_id" value="〇〇〇" />
  <ul>
    <li><a href="#" data-kushi="chicken">鳥精</a></li>
    <li><a href="#" data-kushi="pork">豚精</a></li>
    <li><a href="#" data-kushi="zebra">丸ごとシマウマ</a></li>
  </ul>
</form>
<script>
  $('form ul').on('click', 'a', function(e){
    e.preventDefault(); // ←「aタグ」クリックによるページ遷移を無効にする。
    
    $(this).parents('form')
           .append('<input type="hidden" name="kushi" value="' + $(this).data('kushi') + '" />')
           .submit();
  });
</script>

※「aタグ」クリックのページ遷移は無効にする:他でのイベントが絡む可能性を考慮して「return false」じゃなく「preventDefault()」。

tdタグをクリックでtdタグ内のチェックボックスをゴニョゴニョ

$(〇〇〇).on('click', 'td', function(e) {
  if ( e.target.localName == 'input' ) {
    // 親への伝播ストップ
    e.stopPropagation();
  }
  else {
    $(this).find('[type=checkbox]').click();
  }
  
  ~ 処理 ~
});

関連項目

jquery tdクリックでその行の色変更とチェックボックス・ラジオボタンにチェック