jQueryでボタンがクリックされたりとかリンクが押されたりしたとき、
そのイベントというのはその下にある親要素にまで伝播してしまいます。
子要素だけで処理したいのに下の要素まで余計なイベントは発生させたくないですよね。
ということで子要素のイベントをその下の要素にまで伝播させない方法を紹介します。
子要素のイベントが親要素に伝わると困ること
子要素のイベントが親要素にも伝わる・・・
最初にこれがどういうことかについて少し説明します。
例えば次のようにボタン要素の中にリンク要素があるとしましょう。
1 2 3 |
<button class="outer_btn"> <a href="" class="inner_link">ボタン上のリンク</a> </button> |
ボタンが親要素で、その下にあるリンクが子要素です。
そしてこのボタン、リンクがクリックされたときにclickイベントを登録します。
例えば次はそれぞれが押されたときにアラート表示するコード例
1 2 3 4 5 6 7 8 |
jQuery(function(){ jQuery('.outer_btn').on('click', function(){ alert('ボタンが押されたよ'); }); jQuery('.inner_link').on('click', function(){ alert('リンクが押されたよ'); }); }); |
このコードだとリンクが押されたときは「リンクが押されたよ」のアラートだけ表示されそうな気がします。
しかし実際はリンク押下後に
「リンクが押されたよ」 ⇒ 「ボタンが押されたよ」
のようにボタンについてもメッセージが表示されてしまうんですよね。
実際にどういう動きをするかは次のCodePenでリンククリックすれば分かります。
See the Pen 【jQuery】子要素のイベントは親要素にも伝わる by ぴー助 (@pisuke-code) on CodePen.
こういう風に子要素の下にまでイベントが伝わるのがイベント処理の厄介な所です。
イベントを親要素で発生させないためには
子要素がクリックとかされたときに親要素でそのイベントを発生させない方法は2つあります。
それが次の2つの方法
- stopPropagationを使う方法
- return falseを使う方法
親要素に伝搬させないだけの目的なら stopPropagation を使うのが一番安全で確実です。
ではこれらの方法の使い方についてコード例などと一緒に紹介していきます。
stopPropagationの使い方
stopPropagation はあるイベントに対してそれ以上伝搬を止めるために使われる関数です。
その使い方は簡単で伝搬をストップさせたいイベント内で呼び出すだけ
例えば先ほどの例でいうなら次のような感じで使います。
1 2 3 4 5 6 7 8 9 |
jQuery(function(){ jQuery('.outer_btn').on('click', function(e){ alert('ボタンが押されたよ'); }); jQuery('.inner_link').on('click', function(e){ alert('リンクが押されたよ'); e.stopPropagation(); }); }); |
リンクイベント内で渡されたイベントに対して e.stopPropagation(); として呼び出しています。
これでリンククリック時に「ボタンが押されたよ」アラートの表示を防げます。
イベントの伝搬を止めるならこちらを使うのが確実ですね。
次で紹介する方法も使えますが、大抵はこちらを使うと思います。
return false; を使う方法
次はイベントをストップさせるのに return false; を使う方法です。
使い方は簡単でイベント内で return false; を使って帰るだけ
ボタンとリンクの例でいうなら次のようなコードになります。
1 2 3 4 5 6 7 8 9 |
jQuery(function(){ jQuery('.outer_btn').on('click', function(e){ alert('ボタンが押されたよ'); }); jQuery('.inner_link').on('click', function(e){ alert('リンクが押されたよ'); return false; }); }); |
これでもリンク押下時に「ボタンが押されたよ」アラートを表示するのを防げます。
ただし return false; の問題点は要素のデフォルトイベントまで停止させてしまうことです。
その悪影響の例をいくつか挙げるとすると次のようなこと
- リンク押下時にイベントストップ
⇒ リンクでのページ遷移機能もストップするのでページ遷移が起こらなくなる
- チェックボックス押下時にイベントストップ
⇒ チェックボックス本来の機能が停止してオン・オフができなくなる
こういう風な予期しない動作が出てしまうのが return false; を使う問題点です。
簡単に使えるテクニックですが結構デメリットもあるので使わないのが安全かもしれません。
しかも return false; なんてありふれた文なのでエラーを見つけるのも大変です。
なので僕自身は stopPropagation を使うことが多いです。
ここまでのまとめ
イベントを親要素に使えない方法をまとめると次の通り
- stopPropagation を使う方法
イベントをストップさせたい要素のイベントに対して e.stopPropagation; のように使用
デフォルトのイベントまでは停止しないのでこちらを使う方が確実・安全 - return false; を使う方法
イベントをストップさせたいイベント内で使用
要素のデフォルトイベントまで止めてしまうのでもし使うときは要注意!
なるべく stopPropagation を使うのがバグなどの原因になりにくくて安全な方法です。
ということで親要素にイベントを伝搬させない方法についてまとめました。
ではでは($・・)/~~~