zishu's blog

zishu's blog

一个热爱生活的博主。https://zishu.me

イベントリスナー関数、およびイベントのキャプチャとバブリングメカニズム

イベントは一般的にブラウザとユーザー操作の間のインタラクションに使用されます。ユーザーが特定の操作を実行すると、ブラウザが反応し、バインドされたイベントをトリガーします。イベントフローでは、イベントが発生すると、要素ノードとルートノードの間で合意された順序で伝播します。イベントが通過するすべてのノードはイベントの影響を受け、この伝播プロセスは DOM イベントフローと呼ばれます。

関数イベント#

イベントは一般的にブラウザとユーザー操作の間のインタラクションに使用されます。ユーザーが特定の操作を実行すると、ブラウザが反応し、バインドされたイベントをトリガーします。

イベントフローでは、イベントが発生すると、要素ノードとルートノードの間で合意された順序で伝播します。イベントが通過するすべてのノードはイベントの影響を受け、この伝播プロセスは DOM イベントフローと呼ばれます。

image

true はキャプチャ、false はバブリングで、デフォルトはバブリングイベントです。

1.addEventListener ()--イベントリスナー関数の追加#

要素にイベントを追加します。複数のイベントがある場合、上書きされず、順に実行されます。

<div id="demo">dom</div>
<script>
    document.getElementById('demo').addEventListener("click", myfun)
    document.getElementById('demo').addEventListener("click", myfun1)

    function myfun() {
        console.log('イベントリスナー関数')
    }

    function myfun1() {
        console.log('addEventListener')
    }
</script>

image

注意:
1. ここには一つの細部があります。addEventListener () には二つのパラメータがあり、最初はトリガー条件を示し、二つ目はトリガーイベントを示します。
通常、二つ目のパラメータには関数名をそのまま書き、パラメータ()を付けません。もし()を付けると、即座に実行され、最初のパラメータが要求する条件をトリガーする必要がありません。

2. ここでイベントをバインドする際、イベント名は定義された変数名と同じにしてはいけません。そうしないと無効になります。

2.removeEventListener ()--イベントリスナー関数の削除#

以下のデモでは、マウスが div 内を移動するとランダムな数が表示され、ボタンをクリックするとイベントリスナー関数が削除されます。

<!-- css -->
<style>
    #demo {
        width: 100px;
        height: 100px;
        border: 1px solid #000;
    }
</style>

<!-- html -->
<div id="demo"></div>
<input type="button" value="クリックして削除" onclick="remove()">
<div id="show"></div>

<!-- js -->
<script>
    document.getElementById('demo').addEventListener("mousemove", myfun)
    function myfun() {
        document.getElementById('show').innerHTML = Math.random()
    }

    function remove() {
        document.getElementById('demo').removeEventListener("mousemove", myfun)
    }
</script>

3. イベントのキャプチャとバブリングを利用して何かをする#

addEventListener () と removeEventListener () は実際には三つのパラメータを持っています。最初はトリガー条件を示し、二つ目はトリガーイベント、三つ目のパラメータは通常省略できますが、その意味を理解しておく必要があります。

ブール値で表現され、true または false で、デフォルトは false です。

image

  • true はキャプチャ段階でイベントハンドラを呼び出すことを示します。
  • false はバブリング段階でイベントハンドラを呼び出すことを示します。

画像からわかるように、キャプチャ段階はバブリング段階よりも先に行われるため、true イベントは false イベントよりも先にトリガーされます。複数の true イベントは順にトリガーされ、複数の false イベントは後に書かれたものが先にトリガーされます。

結論:前に書かれた true イベント > 後に書かれた true イベント > 後に書かれた false イベント > 前に書かれた false イベント

したがって、このパラメータを利用して、同じ要素の異なるイベントのトリガー順序を制御できます。

<div id="out">
    <p>最外層</p>
    <div id="middle">
        <div id="inner">最内層</div>
    </div>
</div>

<!-- 第一のケース -->
<script>
    var out = document.getElementById('out'); 
    var middle = document.getElementById('middle'); 
    var inner = document.getElementById('inner'); 
    //innerをクリックすると、トリガー順序は:inner-------middle------out
    out.addEventListener('click',function(){alert("私は最外層です");},false);   
    middle.addEventListener('click',function(){alert("私は中間層です");},false);    
    inner.addEventListener('click',function(){alert("私は最内層です");},false); 
</script>

<!-- 第二のケース -->
<script>
    var out = document.getElementById('out'); 
    var middle = document.getElementById('middle'); 
    var inner = document.getElementById('inner'); 
    //innerをクリックすると、トリガー順序は:out------middle-------inner
    out.addEventListener('click',function(){alert("私は最外層です");},true);   
    middle.addEventListener('click',function(){alert("私は中間層です");},true);  
    inner.addEventListener('click',function(){alert("私は最内層です");},true); 
</script>

<!-- 第三のケース -->
<script>
    var out = document.getElementById('out'); 
    var middle = document.getElementById('middle'); 
    var inner = document.getElementById('inner'); 
    //innerをクリックすると、トリガー順序は:out------inner-------middle
    out.addEventListener('click',function(){alert("私は最外層です");},true);   
    middle.addEventListener('click',function(){alert("私は中間層です");},false);    
    inner.addEventListener('click',function(){alert("私は最内層です");},false);
</script>

<!-- 第四のケース -->
<script>
    var out = document.getElementById('out'); 
    var middle = document.getElementById('middle'); 
    var inner = document.getElementById('inner'); 
    //innerをクリックすると、トリガー順序は:out-------middle------inner
    out.addEventListener('click',function(){alert("私は最外層です");},true);   
    middle.addEventListener('click',function(){alert("私は中間層です");},true);  
    inner.addEventListener('click',function(){alert("私は最内層です");},false);
</script>

<!-- 第五のケース -->
<script>
    var out = document.getElementById('out'); 
    var middle = document.getElementById('middle'); 
    var inner = document.getElementById('inner'); 
    //innerをクリックすると、トリガー順序は:middle-------inner------out
    out.addEventListener('click',function(){alert("私は最外層です");},false);   
    middle.addEventListener('click',function(){alert("私は中間層です");},true);  
    inner.addEventListener('click',function(){alert("私は最内層です");},false);
</script>

<!-- 第六のケース -->
<script>
    var out = document.getElementById('out'); 
    var middle = document.getElementById('middle'); 
    var inner = document.getElementById('inner'); 
    //innerをクリックすると、トリガー順序は:out-------inner------middle
    out.addEventListener('click',function(){alert("私は最外層です");},true);   
    middle.addEventListener('click',function(){alert("私は中間層です");},false);    
    inner.addEventListener('click',function(){alert("私は最内層です");},true);
</script>

4. イベントハンドラ#

  1. HTML イベントハンドラ
<button onclick="test()">テスト</button>
<script>
    function test() {
        alert("HTMLイベントハンドラ");
    }
</script>

1. 利点:イベントハンドラ内のコードは、グローバルスコープ内の任意の変数にアクセスできます。
2. 欠点:時差問題、拡張されたスコープチェーンが異なるブラウザで異なる結果を引き起こす可能性、html コードと js コードの高度な結合。

  1. DOM0 レベルイベントハンドラ
<button id="btn">テスト</button>
<script>
    var btn = document.getElementById("btn");
    btn.onclick = function test() {
        alert("DOM0レベルイベントハンドラ");
    }
</script>

1. 利点:コードがシンプルで、ブラウザの互換性が良く、html コードと js コードの高度な結合の問題を解決します。
2. 欠点:一つの要素には一つのイベントハンドラしかバインドできず、イベントバブリング中にのみ実行されます。

  1. DOM2 レベルイベントハンドラ

このレベルのイベントハンドラは、イベントキャプチャとバブリングメカニズムを利用しています。

<button id="btn">テスト</button>
<script>
    var btn = document.getElementById("btn");

    // イベントリスニング
    btn.addEventListener("click", function() {
        alert("DOM2レベルイベントハンドラ、私はキャプチャ段階で実行されます");
    }, true);

    btn.addEventListener("click", function() {
        alert("DOM2レベルイベントハンドラ、私はバブリング段階で実行されます");
    }, false);

    // イベントリスナーの削除
    var fun = function() {
        alert("私は削除されます");
    }
    btn.addEventListener("click", fun, false);
    btn.removeEventListener("click", fun, false);
</script>

1. 利点:イベント処理のキャプチャとバブリング段階の両方を同時にサポートし、一つの要素に複数の処理関数をバインドできます。
2. 欠点:IE はサポートしていません。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。