matsuo

jQuery のバブリング、preventDefault() や stopPropagation() の使用例

jQuery のイベントのバブリング (伝播) については下記のサイトがほんとに分かりやすくて、読んでいただければもうあらためて書くことはないのですが、

jQueryのバブリングと、「return false;」「e.stopPropagation();」「e.preventDefault();」について (ふじこのプログラミング奮闘記

3行でまとめると、

  • クリックなどのイベントは、子要素から親要素へと伝播される(バブリング)
  • preventDefault() は、その要素のイベントをキャンセルし、stopPropagation()は、親要素への伝播をキャンセルする。
  • return false; を使うと、その要素のイベントも親要素への伝播も両方キャンセルする。

という感じです。

で、実際の使いどころといいますか、使用例をサンプルでご紹介したいと思います。

サンプル A

http://tam-matsuo.github.io/jquery-event/

  • ボタンをクリックすると、全画面でモーダルウィンドウ的なものが開きます。
  • 背景の div要素の子として、ウィンドウや閉じるボタンが配置されています。
  • ウィンドウには別サイトへのリンクボタンと、閉じるボタンがあります。
  • 背景をクリックすると、モーダルウィンドウは閉じられます。

このサンプルA では preventDefault() や stopPropagation() を使っているのですが、ではもし使わないとどうなるか? というのを先に見ていただくと分かりやすいかも。
↓使わない場合の例、サンプルB はこちらです。

サンプル B (不具合あり)

http://tam-matsuo.github.io/jquery-event/index-b.html

コードはこれだけ。

ウインドウを表示したあと、背景をクリックするとウィンドウは閉じられます。
でも困ったことに、ウィンドウの中身(白い部分)をクリックしてもウィンドウが閉じられてしまいます。外部サイトへのリンクボタンも有効になりません。
つまり、「背景をクリックすると閉じる」という設定が、背景の子要素をクリックしたときも効いてしまうんですね。子から親に、イベントは伝播するから。

では、HTMLを組み替えて、背景とウィンドウ本体を親子関係にならないようにするか?
その方法でも解決できますが、preventDefault() や stopPropagation() を使ってイベントの伝播を制御してやれば、親子関係のままでもうまくいきます。


ということで、先のサンプルA のコードはこんな感じ。

ウィンドウ本体をクリックした際は、親(背景)への伝播をやめる。
閉じるボタンをクリックした際は、親(背景)へ伝播する。
という処理を入れました。
これで、背景の子要素がクリックされたときの処理を制御できています。

以上、イベントのバブリングに関する preventDefault() / stopPropagation() の使用例でした。

新しいウェブ体験を作ろう TAMのPWA開発
お問い合わせはこちら