イベントの伝搬を中断するには
【開発環境】
OS:Win11(64ビット)
VSCode1.72.2、
クロム
【キャンセルしたい場合】
HTML ページ内でイベントが発生した場合、親要素へとイベントが伝搬していきますが、途中でこれ以上の伝搬を行わないようにイベントの伝搬を停止することができます。
また、同じターゲットの同じイベントに対して複数のイベントリスナーを登録できますが、途中で他のまだ呼び出されていないイベントリスナーを呼び出さないように停止することもできます。
【イベントの伝搬を止める】
Event オブジェクトの stopPropagation メソッドを使用すると、イベントの伝搬を止めることができます。
書式:event.stopPropagation()
例えば
イベントが発生し呼び出されたイベントリスナーの中でこのメソッドが実行されると、これ以降のイベントの伝搬(キャプチャリングフェーズ、バブリングフェーズのどちらの場合でも)が行われなくなります。
イベントが呼び出されるときに引数として渡されてくる Event オブジェクトに対して stopPropagation メソッドを実行します。
例文
let target = document.getElementById('xxx');
target.addEventListener('click', function(event){
console.log('Hello');
event.stopPropagation();
});
サンプルコード
stop.cssのコード
div {
background-color:#E5E5E5;
border:5px solid #8f8f8f;
}
#outer{
width:300px;
}
#inner{
margin:20px;
padding:20px;
background-color:#ffff00;
text-align:center;
}
stop.jsコード
let outer = document.getElementById('outer');
let inner = document.getElementById('inner');
let btna = document.getElementById('btnA');
let btnb = document.getElementById('btnB');
outer.addEventListener('click', function(){
console.log('outer');
});
inner.addEventListener('click', function(event){
console.log('inner');
event.stopPropagation();
});
btna.addEventListener('click', function(){
console.log('buttonA');
});
btnb.addEventListener('click', function(event){
console.log('buttonB');
event.stopPropagation();
});
ブラウザを立ち上げる
最初に左側の input 要素「buttonA」をクリックしてみます。 click イベントは親要素へと伝搬されていきますが、内側の div 要素で呼び出されたイベントリスナー内で stopPropagation メソッドを実行しているので click イベントの伝搬は止まりそれ以降は行われません。
次に右側の input 要素「buttonB」をクリックしてみます。右側の input 要素で呼び出されたイベントリスナー内で stopPropagation メソッドを実行しているので click イベントの伝搬はそれ以降は行われませせん。
【他のイベントリスナーの呼び出しを止める方法】
Event オブジェクトの stopImmediatePropagation メソッドを使用すると、同じイベントに対して登録されたまだ呼び出されていない他のイベントリスナーの呼び出しを止めることができます
書式:event.stopImmediatePropagation()
addEventListener メソッドを使ってイベントリスナーを登録する場合、同じターゲットの同じイベントに対して複数のイベントリスナーを登録することができます。イベントが発生すると登録された順番にイベントリスナーが呼び出されます。
イベントが発生し呼び出されたイベントリスナーの中で stopImmediatePropagation メソッドを実行すると、同じイベントに対して登録されていてまだ呼び出されていないイベントリスナーが呼び出されなくなります。
また stopPropagation メソッドを実行したときと同じように親要素へのイベント伝搬も行われなくなります。
サンプルコード
stop.css
同じコード
stop2.js
let outer = document.getElementById('outer');
let btna = document.getElementById('btnA');
let btnb = document.getElementById('btnB');
outer.addEventListener('click', function(){
console.log('outer');
});
btna.addEventListener('click', function(event){
console.log('ActionA1');
//親への伝播を中止させるが、下のコードは実行される
event.stopPropagation();
});
btna.addEventListener('click', function(){
console.log('ActionA2');
});
btnb.addEventListener('click', function(event){
console.log('ActionB1');
//同イベントリスナーの中止、ここから下のコードは実行されない
event.stopImmediatePropagation();
});
btnb.addEventListener('click', function(){
console.log('ActionB2');
});
ブラウザを立ち上げて、buttonAをクリックする。
呼び出された最初のイベントリスナーの中で stopPropagation メソッドを実行しているので、
親要素へのイベントは伝達しません。ただ同じ要素の同じイベントに対するイベントリスナーは実行されるため、二つ目のイベントリスナーも呼び出されています。
親要素「outer」は表示されないが、子同士は表示される。
buttonBをクリックする。
呼び出された最初のイベントリスナーの中で stopImmediatePropagation メソッドを実行しているので親要素へのイベント伝達も停止し、同じ要素の同じイベントに対するイベントリスナーの中で、まだ実行されているイベントリスナーも呼び出されなくなります