職案人

求職・歴史・仏教などについて掲載するつもりだが、自分の思いつきが多いブログだよ。適当に付き合って下さい。

JS--イベントの伝播の流れ:イベントフェーズ

2024年09月02日 | JavaScript

イベントの伝搬

【開発環境】
OS:Win11(64ビット)
VSCode1.72.2、
クロム

【イベントフェーズ】



この HTML ページの中の 'start' ボタンがクリックされたときに、クリックイベントがどのように発生し、どのように伝搬していくのかを理解する。

【フェーズの種類】
1、キャプチャリングフェーズ (Capturing phase)
2、ターゲットフェーズ(Target Phase)
3,バブリングフェーズ(Bubbling Phase)

キャプチャリングフェーズ
HTML ページの中の 'start' ボタンがクリックされると、一番最上位のオブジェクトである Window オブジェクトでまず click イベントを発生させ、その後 DOM ツリーの構造に沿って伝播する。Document オブジェクト→ html 要素→、 body 要素→ div 要素 →input要素へと、下に向かって行き、発生要素を見つけ出す。


但し、キャプチャリングフェーズの時に発生したイベントは、ほとんどの場合使用されません。要素の属性や要素のプロパティにイベントハンドラを登録した場合でも、addEventListener メソッドでイベントリスナーが登録され場合でも、イベントは実行されない。

【ターゲットフェーズ】
キャプチャリングフェーズのあと、実際にイベントが発生した要素で click イベントが発生する段階をターゲットフェーズと呼びます


ターゲットフェーズでイベントが発生すると、そのイベントに対して登録されたすべてのイベントハンドラやイベントリスナーが呼び出されます。

【バブリングフェーズ】
今度は逆にイベントが発生した要素の親要素である div 要素から、 body 要素、 html 要素、 Document オブジェクト、 Window オブジェクトまで DOM ツリーを上へ向かって順番に click イベントが発生していきます。

バブリングフェーズで発生したイベントも、ごく一部のイベントを除いてそのイベントに対して登録されたイベントハンドラやイベントリスナーが呼び出されます。 focus イベントや blur イベントは Event.bubbles プロパティが false となっているため、バブリングフェーズによるイベントの伝搬を行いません。

サンプルコード
フェーズ.html

外部css:フェーズ.css

div {
    background-color:#E5E5E5;
    border:5px solid #8f8f8f;
  }
  #outer{
    width:300px;
  }
  #inner{
    margin:20px;
    padding:20px;
    text-align:center;
  }

外部js:フェーズ.js
let outer = document.getElementById('outer');
    let inner = document.getElementById('inner');
    let btn = document.getElementById('btn');

    outer.addEventListener('click', function(){
        console.log('outer');
    });

    inner.addEventListener('click', function(){
        console.log('inner');
    });

    btn.addEventListener('click', function(){
        console.log('btn');
    });
ブラウザを立ち上げる


ボタンをクリックすると、最初に input 要素をクリックしてみます。すると、 input 要素のイベントリスナーだけでなく、親要素の内側の div 要素、そしてさらに親要素の外側の div 要素のイベントリスナーが呼び出されます。

それ以外の所をクリックすると、内側の div 要素のイベントリスナーが呼び出されたあと、親要素の外側の div 要素のイベントリスナーが呼び出されます


【キャプチャリングフェーズで発生したイベントでイベントリスナーを呼び出す】
キャプチャリングフェーズで発生したイベントをイベントリスナーを呼び出すには、 addEventListener メソッドでイベントリスナーが登録されるときに、 3 番目の引数に true または {capture: true} を指定します。
 
書式
button.addEventListener('click', butotnClick,true);
button.addEventListener('click', butotnClick, {capture: true});

キャプチャリングフェーズでのイベントでイベントリスナーを呼び出すように設定した場合、バブリングフェーズでのイベントではイベントリスナーが呼び出されなくなります。
 
サンプルコード
外部css:フェーズ.css
外部JS:フェーズ2.js
let outer = document.getElementById('outer');
    let inner = document.getElementById('inner');
    let btn = document.getElementById('btn');

    outer.addEventListener('click', function(){
        console.log('outer');
    }, true);

    inner.addEventListener('click', function(){
        console.log('inner');
    }, true);

    btn.addEventListener('click', function(){
        console.log('btn');
    }, true);
赤字は更新した所
ブラウザを立ち上げ、ボタンをクリックする。
今回は addEventListener メソッドの 3 番目の引数に true を設定しているのでキャプチャリングフェーズのイベントが発生したときにイベントリスナーが呼び出されます。

最初に input 要素をクリックしてみます。すると、まず外側の div 要素、内側の div 要素、最後に実際にイベントが発生した input 要素のイベントリスナーが呼び出されます。


次に内側の div 要素をクリックしてみます。すると外側の div 要素のイベントリスナーが呼び出されたあと、実際にイベントが発生した内側の div 要素のイベントリスナーが呼び出されます。



コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする