クリックやドラッグ等のイベントが発生した時、そのイベントは要素の上層に向けて伝搬します。いわゆるバブリングと呼ばれるイベントの伝搬の仕組みです。
イベントの伝播の流れはstopPropagationメソッドやstopPropagationオプションを利用することで制御することもできるようです。その挙動を確認しました。
A-0、A-1、A-2とネストする要素を作成し、それぞれにイベントを登録したコードを準備します。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>イベントの伝搬の挙動確認</title> <script type="text/javascript"> function load() { document.getElementById('A-0').addEventListener('click', function(event) { console.log('A-0 clicked.'); }, false); document.getElementById('A-1').addEventListener('click', function(event) { console.log('A-1 clicked.'); // event.stopPropagation(); // (1) }, false); document.getElementById('A-2').addEventListener('click', function(event) { console.log('A-2 clicked.'); }, false); } </script> </head> <body onload="load();"> <div id="A-0"> A-0 <div id="A-1"> A-1 <div id="A-2"> A-2 </div> </div> </div> </body> </html>
stopPropagationメソッド
上述のコードでA-2をクリックすると、バブリングが行われて下記のような結果となります。
A-2 clicked. A-1 clicked. A-0 clicked.
イベントの伝搬を止めるには、event.stopPropagationを利用します。(1)のコメントアウトを外してA-2をクリックすると、A-1で伝搬が止まりました。
A-2 clicked. A-1 clicked.
useCaptureオプション
addEventListenerの第三引数がuseCaptureオプションです。イベントの伝搬方向はこのオプションで決めることができ、false(デフォルト)であればイベント発生要素から上流に向かって伝搬、trueであれば上流からイベント発生要素に向かって伝搬するようになります。
A-0、A-1、A-2全部のuseCaptureをtrueにしてA-2をクリックすると、下記のような結果になりました。
A-0 clicked. A-1 clicked. A-2 clicked.
stopPropagationメソッドとuseCaptureオプションの併用には注意が必要そうです。A-0のuseCaptureをtrueにし、(1)のコメントアウトを外してA-2をクリックすると、stopPropagationをすり抜けて実行されたかのような挙動になりました。
A-0 clicked. A-2 clicked. A-1 clicked.