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(); } ~ 処理 ~ });