LoginSignup
26
28

More than 3 years have passed since last update.

JavaScriptのイベント伝播って?(addEventListenerの第三引数についても)

Last updated at Posted at 2019-07-06

JavaScriptのイベント伝播

今日はaddEventListenerの引数について調べていたら、
イベント伝播?バブリング?キャプチャリング??!と知らないことだらけだったので、
調べてまとめてみます!

まず大前提:イベントは伝播するということ

<!--HTML-->
<div id="parent">     <!--親-->
  <div id="child">    <!--子-->
  </div>
</div>

このように親子関係になっている二つの要素に、イベントリスナを登録します。

document.getElementById('parent').addEventListener('click',()=>{
   alert('親だよ');
});
document.getElementById('child').addEventListener('click',()=>{
   alert('子だよ');
});

このように親子関係で同じイベントリスナを登録し子をクリックすると、親のイベントも一緒に発動します。

イベントの伝播の道筋

イベントが発生したら、以下の道筋を辿ります。

①キャプチャーフェーズ
windowからその子へ、そしてその子へ、、と順従に目的のノードに向かってイベントが走るフェーズ。
②ターゲットフェーズ
イベントが発生した要素にイベントが伝わるフェーズ
③バブリングフェーズ
イベント発生元から親へ向かって順々にイベントが走るフェーズ。

え!二回も走ってるの!?:robot:
と思いました。じゃあどっちでイベント伝播してるの?と。

addEventListenerの第三引数

それを定めることができるのがaddEventListenerの第三引数らしいです。

element.addEventListener('click',event,true/false);

true・・・キャプチャーフェーズ時に発火する。(つまり親から先に発火)
false・・・バブリングフェーズ時に発火する・(つまり子から先に発火)←初期値

これでどちらから発火させるか?をコントロールすることができます。
なんならキャプチャーフェーズ時とバブリングフェーズ時に二回発火も可能みたいです。

使い方によっては面白いことができそうです。

伝播やめて!!!

stopPropagation()を使えばいいそうです。

document.getElementById('parent').addEventListener('click',()=>{
   alert('親だよ');
});
document.getElementById('child').addEventListener('click',(e)=>{
   e.stopPropagation();
   alert('子だよ');
});

これで子をクリックしても、親のイベントリスナがバブリングすることがなくなります。

おまけ:登録したイベントリスナを無効にしたい

removeEventListener
・・・addEventListenerで登録したイベントリスナーを削除する。
こいつを使えばおっけーです。ただし、addEventListenerの第二引数を無名関数にすると使えないので注意!

function message() {
   console.log('Erase me!');
}

element.addEvenetListener('click',message) //登録

element.removeEventListener('click',message)  //削除
26
28
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
28