JavaScriptやjQueryでクリックイベントを設置した際に、そのイベントを子要素、孫要素へ伝播させないための処理を紹介します。
よくあるケースとして、ライトボックスのようなしくみを構築したときを考えます。
ブラウザの画面全体をグレーアウトして、その上のレイヤに画像、動画やフォームなどのコンテンツを配置します。
<div class="lightbox">
<div class="grayout">
<div class="contents">
画像、動画やフォームなどのコンテンツ
</div>
</div>
</div>
コンテンツエリアを除く、グレーアウトエリアをクリックすると、ライトボックスをクローズするような処理を考えます。
stopPropagationを使う方法
例えばjQueryでグレーアウトしたエリアをクリックすると、ライトボックスをクローズするような処理を追加します。
$('.grayout').click(function(){
$('.lightbox').fadeOut();
});
しかし、そのままでは子要素である「class=”contents”」のコンテンツエリアまでイベントが伝播してしまい、コンテンツエリアをクリックしてもクローズしてしまいます。
そこで、コンテンツエリアをクリックしてもイベントが発生しないように以下の処理を追加します。
$('.contents').click(function(event){
event.stopPropagation();
});
これで今回の伝播の問題は達成できるのですが、コンテンツエリアに他のイベントを設定している場合、その処理に悪影響を与える場合があります。
コンテンツエリア以外でイベント発火
stopPropagationの問題を避けるため、以下の方法があります。
$(document).on('click', function(event) {
if (!$(event.target).closest('.contents').length) {
$('.lightbox').fadeOut();
}
});
画面全エリアにクリックイベントをセットして、その中でクリックエリアを判定して、処理を実行する方法です。
後者のほうがシンプルで良さそうですね。
忘れてしまいがちなので、メモまで。