JSにおけるイベントバブルとキャプチャ

5337 ワード

イベントバブルとイベントキャプチャ

および は、それぞれ および 社によって提案され、この2つの概念は、ページ内のイベントフロー(イベント発生順序)の問題を解決するためである.次のコードを考えて、html->head、bodyなどのコードを書かないで、自分で頭で補います.

Click me!


上のコードの1つのdiv要素の中にpサブ要素があります.もし2つの要素にclickの処理関数があれば、どの関数が最初にトリガーされるかどうやって知ることができますか?この問題を解決するためにマイクロソフトとネットシーンは2つのほぼ逆の概念を提出した.

イベントバブル


マイクロソフトは (event bubbling)というイベントフローを提案した.事件の泡は、石を水に投げ込むと、水底から水面に泡が出ることをイメージしている.つまり、イベントは最内層の要素から始まり、documentオブジェクトまで上へ伝播します.
したがって、イベントバブルの概念の下でp元素上でclickイベントが発生する順序はp -> div -> body -> html -> documentであるべきである.

イベントのキャプチャ


ネットワーク・ビューは、 (event capturing)という別のイベント・フローを提案する.イベントバブルとは逆に、イベントは最も特定の要素まで最外層から発生します.
したがって、イベントキャプチャの概念の下でp要素上でclickイベントが発生する順序はdocument -> html -> body -> div -> pであるべきである.

addEventListenerの3番目のパラメータ


ネット景とマイクロソフトのかつての戦争はまだ比較的に熱くて、当時、ネット景は捕獲方式を主張して、マイクロソフトは泡の方式を主張します.その後、w 3 cは折衷方式を採用し、戦火を鎮め、統一的な基準を制定した.まず捕獲してから泡が出る.addEventListenerの3番目のパラメータは泡立ちと捕獲のために用意されている.addEventListenerには3つのパラメータがあります.
element.addEventListener(event, function, useCapture)
第1のパラメータはバインドする必要があるイベントであり、第2のパラメータはイベントをトリガーした後に実行する関数であり、第3のパラメータのデフォルト値はfalseであり、イベントバブル段階でイベント処理関数を呼び出すことを示す.パラメータがtrueの場合、イベントキャプチャフェーズで処理関数が呼び出されることを示します.

泡が立つケース

s1
s2
s1.addEventListener("click",function(e){ console.log("s1 "); },false); s2.addEventListener("click",function(e){ console.log("s2 "); },false);

s 2をクリックすると、実行結果は次のとおりです.
http://runjs.cn/detail/kj4jgpli

キャプチャされたケース

s1
s2
s1.addEventListener("click",function(e){ console.log("s1 "); },true); s2.addEventListener("click",function(e){ console.log("s2 "); },true);

s 2をクリックすると、実行結果は次のとおりです.
http://runjs.cn/detail/c3mjulm0

イベントキャプチャvsイベントバブル


イベントキャプチャがイベントバブルとともに存在する場合、イベントはどのようにトリガーされますか.ここでクリックされたDOMノードをtargetノードと記す
  • documentはtargetノードに向かい、キャプチャは前進し、登録されたキャプチャイベントに遭遇すると直ちに
  • の実行をトリガーする.
  • はtargetノードに到達し、イベント(targetノード上で、先にキャプチャするか、先にバブルを起こすかについてはイベントとバブルイベントの登録順序をキャプチャし、先に登録して先に実行する)
  • をトリガする.
  • targetノードはdocument方向に泡を出す前進し、登録された泡イベントに遭遇すると直ちに
  • をトリガする.

    まとめてみると、

  • 非targetノードについては、まず、バブル
  • が実行する.
  • targetノードについては、バブルが発生するか捕獲されるかにかかわらず、先に登録されたイベントが実行される.
    s1
    s2
    s1.addEventListener("click",function(e){ console.log("s1 "); },false); s2.addEventListener("click",function(e){ console.log("s2 "); },false); s1.addEventListener("click",function(e){ console.log("s1 "); },true); s2.addEventListener("click",function(e){ console.log("s2 "); },true);

    s 2をクリックすると、実行結果は次のとおりです.
    http://runjs.cn/detail/fkq3uyqh
    ここで概ね解析して実行結果s 2をクリックすると、clickイベントはdocument->html->body->s 1->s 2(キャプチャ前進)ここでs 1にキャプチャ登録イベントが発見され、出力「s 1キャプチャイベント」はs 2に到達し、目的ノードに到達し、s 2にはバブルとキャプチャイベントが登録され、先に登録されたバブル後登録されたキャプチャは、まずバブルを実行し、出力「s 2バブルイベント」はs 2に実行された後に登録されたイベント、すなわちキャプチャイベントである.出力「s 2キャプチャイベント」の次はバブルフェーズに入り、s 2->s 1->body->html->documen(バブル前進)に従ってs 1にバブルイベントが見つかった場合、「s 1バブルイベント」を出力する

    イベントバブルとイベントキャプチャの適用いべんとぱらめーしょん:イベントエージェントいべんとりーしょんぷらめーしょん


    実際の開発では,イベントフローの特性を利用して,イベントエージェントという方法を用いることができる.
    • red
    • yellow
    • blue
    • green
    • black
    • white

    ページのli要素をクリックしてliの色を出力すると、通常は次のように書きます.
    (function(){
        var color_list = document.getElementById('color-list');
        var colors = color_list.getElementsByTagName('li');
        for(var i=0;i

    イベント・フローのプロパティを使用して、1つのイベント処理関数のみをバインドしても実行できます.
    (function(){
        var color_list = document.getElementById('color-list');
        color_list.addEventListener('click',showColor,false);
        function showColor(e){
            var x = e.target;
            if(x.nodeName.toLowerCase() === 'li'){
                console.log('The color is ' + x.innerHTML);
            }
        }
    })();

    http://runjs.cn/detail/pvsbglwc
    イベントエージェントを使用する利点は、複数のイベント処理関数を1つに減らすだけでなく、異なる要素に対して異なる処理方法を持つことができることです.上記のリスト要素に他の要素(a、spanなど)が追加されている場合、各要素にイベントをバインドする必要がなくなり、イベントエージェントのイベント処理関数を直接変更できます.

    泡が出るか捕獲するか?


    イベントエージェントにとって,イベントキャプチャやイベントバブルフェーズでの処理には明らかな優劣はないが,イベントバブルのイベントフローモデルはすべての主流のブラウザで互換性があるため,互換性の観点からイベントバブルモデルの使用を推奨する.

    IEブラウザ互換性


    IEブラウザはaddEventListener互換性があまり良くなく、IE 9以上でしか使用できません.
    古いバージョンのIEブラウザと互換性を持つには、IEのattachEvent関数を使用します.
    object.attachEvent(event, function)
    2つのパラメータはaddEventListenerと似ており、それぞれイベントと処理関数であり、デフォルトはイベントバブルフェーズ呼び出し処理関数であり、イベント名を書く際には「on」接頭辞(「onload」、「onclick」など)を付けることに注意してください.