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() の使用例でした。