【JavaScript】ブラウザイベントのバブリングと制御

【JavaScript】ブラウザイベントのバブリングと制御

JavaScriptのブラウザイベントにおけるバブリングと制御を解説します。

バブリング

イベントは発生した要素から親要素へと伝搬します。
このことをJavaScriptではバブリングと呼びます。

その様子をサンプルで確認しましょう。

<main id="main">
    <div id="div">
        <button id="button">ボタン</button>
    </div>
<main>

<script type="text/javascript">
    
    function clickMain() {
        console.log("Main Event.");
    }
    
    function clickDiv() {
        console.log("Div Event.");
    }
    
    function clickButton() {
        console.log("Button Event.");
    }
    
    
    let main = document.getElementById('main');
    main.addEventListener('click', clickMain);
    
    let div = document.getElementById('div');
    div.addEventListener('click', clickDiv);
    
    let button = document.getElementById('button');
    button.addEventListener('click', clickButton);
    
</script>
Button Event.
Div Event.
Main Event.

3つの要素maindivbuttonのイベントハンドラーを設定しています。

ボタンをクリックするとコンソールに文字列が出力され、その結果からbuttondivmainの順序でclickイベントを発生したことが分かります。

このようにイベントは親要素へとバブリングします。

バブリング中止(stopPropagation)

stopPropagationメソッドを使い、バブリングを中止することができます。

基本構文

イベントオブジェクト.stopPropagation()

サンプル

<main id="main">
    <div id="div">
        <button id="button">ボタン</button>
    </div>
<main>

<script type="text/javascript">
    
    function clickMain() {
        console.log("Main Event.");
    }
    
    function clickDiv() {
        console.log("Div Event.");
    }
    
    function clickButton1(event) {
        console.log("Button Event1.");
        event.stopPropagation();
    }
    
    function clickButton2() {
        console.log("Button Event2.");
    }
    
    
    let main = document.getElementById('main');
    main.addEventListener('click', clickMain);
    
    let div = document.getElementById('div');
    div.addEventListener('click', clickDiv);
    
    let button = document.getElementById('button');
    button.addEventListener('click', clickButton1);
    button.addEventListener('click', clickButton2);
    
</script>
Button Event1.
Button Event2.

buttonのイベントでeventオブジェクトのstopPropagationメソッドを呼び出しました。
コンソール結果からバブリングがbuttonで止まっていることが分かります。

ただし、同じイベントハンドラーの他の関数(ここではclickButton2)は実行されることに注意してください。

同じイベントハンドラーの他の関数を中止(stopImmediatePropagation)

stopPropagationメソッドは同じイベントハンドラーの他の関数は実行されました。
stopImmediatePropagationメソッドを使うと呼び出されていない他の関数も中止することができます。

基本構文

イベントオブジェクト.stopImmediatePropagation()

サンプル

<main id="main">
    <div id="div">
        <button id="button">ボタン</button>
    </div>
<main>

<script type="text/javascript">
    
    function clickMain() {
        console.log("Main Event.");
    }
    
    function clickDiv() {
        console.log("Div Event.");
    }
    
    function clickButton1(event) {
        console.log("Button Event1.");
        event.stopImmediatePropagation();
    }
    
    function clickButton2() {
        console.log("Button Event2.");
    }
    
    
    let main = document.getElementById('main');
    main.addEventListener('click', clickMain);
    
    let div = document.getElementById('div');
    div.addEventListener('click', clickDiv);
    
    let button = document.getElementById('button');
    button.addEventListener('click', clickButton1);
    button.addEventListener('click', clickButton2);
    
</script>
Button Event1.

規定動作の中止(preventDefault)

Eventオブジェクトのcancelableプロパティがtrueのイベントは、preventDefaultメソッドを使って規定の動作を中止することができます。

規定の動作とは例えばチェックボックスのチェックです。
チェックボックスはクリックするとチェックが付きますが、このメソッドを使うと中止できます。

基本構文

イベントオブジェクト.preventDefault()

サンプル

<main id="main">
    <div id="div">
        <input id="checkbox" type="checkbox">
    </div>
<main>

<script type="text/javascript">
    
    function clickMain() {
        console.log("Main Event.");
    }
    
    function clickDiv() {
        console.log("Div Event.");
    }
    
    function clickCheckbox(event) {
        console.log("Checkbox Event.");
        event.preventDefault();
    }
    
    
    let main = document.getElementById('main');
    main.addEventListener('click', clickMain);
    
    let div = document.getElementById('div');
    div.addEventListener('click', clickDiv);
    
    let checkbox = document.getElementById('checkbox');
    checkbox.addEventListener('click', clickCheckbox);
    
</script>
Checkbox Event.
Div Event.
Main Event.

このチェックボックスはクリックイベントでevent.preventDefault()を実行するため、クリックしてもチェックが付きません。

ただし、バブリングはするので注意してください。