JSイベント学習ノート(一)


イベントフロー


ある要素に祖先要素があり、その祖先要素と同じイベントが定義されている場合、その要素でイベントが発生したとき、その要素と祖先要素との間のイベントの伝達順序の問題に関連します.2つに分けられます.イベントバブル:最も具体的な要素から受信し、イベントハンドラを実行し、documentオブジェクトまでイベントを上に渡します.エレメント上でイベントがトリガーされると、そのイベントハンドラが呼び出されます.エレメントがイベントハンドラを定義していないか、イベントがtrueを返すと、親オブジェクトに渡され、内側から外側まで、すべての親オブジェクトの同じイベントがアクティブになります.documentオブジェクトまでアップロードします.イベントキャプチャ:逆に、最外層のdocumentからキャプチャしてから、最も具体的な要素に順次伝達します.すなわち、内部要素でイベントがトリガーされた後、外部要素によってイベントがキャプチャされ、独自にバインドされたイベントハンドラが実行されます.イベントを内部要素に下に渡します.通常、イベントバブルが使用されます.

DOM 2レベルイベントフロー


キャプチャフェーズ、ターゲットフェーズ(実際のターゲットがイベントを受信)、イベントバブルフェーズ(特定のターゲットがイベントに応答するフェーズ)の3つのフェーズに分けられます.すなわち,イベントはまずdocumentからターゲットオブジェクトまで伝達され,その後documentにバブル方式で伝達される.ただし、要素を含む具体的なイベントハンドラは、イベントを追加する関数のパラメータによって設定されます.すなわち、親要素はイベントを先に受信するに違いないが、キャプチャ時に実行するとは限らない.domイベントフローをサポートするブラウザの多くは、キャプチャフェーズではイベントターゲットに関与しないが、chrome、Firefox、IE 9などのブラウザは、キャプチャフェーズでイベントオブジェクト上のイベントをトリガーすることができ、結果として、ターゲットオブジェクト上でイベントを操作する2つの機会(フェーズ)があることを規定している.

二イベントハンドラ


A.htmlイベントハンドラ


すなわち、対応するイベントの関数は、「on」で始まる.イベントハンドラのコードは、実行時にグローバル役割ドメインの任意のコードにアクセスする権利を有する.関数には、カスタムではないローカル変数even、すなわちイベントオブジェクトがあり、関数のthisはイベントのターゲット要素を指す.拡張役割ドメイン:with文この方式の欠点p-350

B.JavaScript指定イベントハンドラ


1.DOM 0級イベントハンドラ
この方式はjsコードとhtmlを緊密に結合させる.JavaScriptを使用してイベントハンドラを指定します.操作対象のイベントハンドラのプロパティに関数を割り当てます.例えばbtn.onclick=function(){}. 注意:JSコードがバインドイベントに実行されるまでイベントハンドラは指定されません.したがって、これらのコードがページ内でボタンの後ろにある場合、ボタンをクリックしても反応しない可能性があります.この方式で指定されたイベントハンドラは、要素のメソッドとみなされ、要素の役割ドメインで実行され、thisは現在の要素を参照します.このように指定すると、イベントフローのバブルフェーズで処理されます.DOM 0レベルは、同じイベントに対して1つのDOM要素上で1つのイベントハンドラのみをサポートし、その後は前のイベントハンドラを上書きします(1つのDOM要素に異なるイベントをバインドできます).バインドされたイベントの削除:btn.onclick=null
2 . DOM 2レベルのイベントハンドラは、DOMノードに対してaddEventListener()およびremoveEventListener()を使用してイベントハンドラを設定および削除する方法を規定しています.この2つの方法には、3つのパラメータが含まれています.
  • パラメータ1:指定イベント名
  • パラメータ2:指定イベントハンドラ
  • パラメータ3:ブール値、trueは、イベントを受信したオブジェクトがイベントキャプチャフェーズでイベントハンドラを呼び出し、falseは、イベントを受信したオブジェクトがバブルフェーズで呼び出されるまで待たなければならないことを示す.例:
  • //html  
    <div id="outside">I am outside
    <div id="inside">I am inside</div>
    </div>
    //js  
    window.onload=function(){
        var outside = document.getElementById("outside");
        outside.addEventListener("click",function(){alert("I am outside")},true);//        
    
        var inside = document.getElementById("inside");
        inside.addEventListener("click",function(){alert("I am inside")},true);
    }

    上のコードのように、外のボックスoutsideのイベントハンドラがtrueに設定されている場合、キャプチャフェーズでイベントがキャプチャされた場合、すぐにそのイベントハンドラが呼び出されます.つまり、内部ボックスをクリックすると、出力順序は「I am outside」です.「I am inside」.外部ケースのtrueをfalseに変更すると、泡立ち段階でハンドラが呼び出されるという意味で、内部ケースをクリックすると、出力順は「I am inside」、「I am outside」となります.
    この方式は、依然として添付された要素の役割ドメインで行われる.この方式の利点は、複数のイベント(同名の上書きされないものを含む)を追加し、追加された順に実行できることである.注意:removeEventListener()のパラメータはaddEventListenerと同じですが、匿名関数は削除できません.つまり、イベントがバインドを解除していないので、有効をクリックします.実際、この関数はaddEventListenerに入力された匿名関数と完全に2つであり、匿名関数参照を持つ変数を入力することによって解決することができる:IEではIE 9のみがDOM 2レベルの方法をサポートする.
    <script type="text/javascript"> window.onload=function(){ var btn = document.getElementById("show"); var handler = function(){alert(this.value)}; btn.addEventListener("click",handler,false); btn.removeEventListener("click",handler,false); } </script>

    さまざまなブラウザとの互換性を最大限に高めるには、イベント・ハンドラをイベント・フローのバブル・フェーズに追加し、イベントがターゲットに達する前にキャプチャする必要がある場合にのみ、イベント・ハンドラをキャプチャ・フェーズに追加することが望ましい.
    3.IEイベントハンドラ
    IEは,attachEvent()とdetachEvent()の2つの方法を実現し,追加されたイベントハンドラをバブルフェーズに追加した.DOM 0およびDOM 2レベルとの違いは、イベントハンドラの役割ドメインがその属する要素(this==バインドイベントの要素)ではなく、グローバル、すなわちthis=windowであることである.同じように、1つの要素に複数のイベントを追加できますが、実行の順序は後で追加される前に実行されます.detachEventはイベントを解除するために使用され、同様に匿名関数パラメータは解除できないので、その参照を渡す必要があります.IE 8以下のプログラム処理関数の実行順序はバインディングの順序とは逆であり,他のIEブラウザは正常である.
    <script type="text/javascript"> window.onload=function(){ var out = document.getElementById("outside"); out.attachEvent("onclick",function(){alert("I am outside")}); //     “onclick”  “click” var inside = document.getElementById("inside"); inside.attachEvent("onclick",function(){alert("I am inside")}); } </script>

    4.クロスブラウザイベントハンドラ
    var EventUtil={
        addHandler:function(element,type,handler){
            if(element.addEventListener){  //DOM2   
                element.addEventListener(type,handler,false);
            }else if(element.attachEvent){ //IE  
                element.attachEvent("on"+type,handler);
            }else{  //DOM0 
                element["on"+type]=handler;
            }
        },
        removeHandler:function(element,type,handler){
            if(element.removeEventListener){  
                element.removeEventListener(type,handler,false);
            }else if(element.detachEvent){ 
                element.detachEvent("on"+type,handler);
            }else{  
                element["on"+type]=null;
            }
        }
    };

    三事件の泡立ちを禁止する


    まず、関連するいくつかの方法と属性について説明します.
  • cancelBubble(HTML DOM Eventオブジェクトのプロパティ):イベントハンドルがイベントを収容オブジェクトに伝播させないようにするには、そのプロパティをtrueに設定する必要があります.
  • stopPropagation(HTML DOM Eventオブジェクトメソッド):伝播プロセスのキャプチャ、ターゲット処理、または発泡段階におけるイベントのさらなる伝播を終了する.メソッドを呼び出すと、ノード上でイベントを処理するプロセッサが呼び出され、イベントは他のノードに割り当てられなくなります.

  • イベントの泡を防ぐプログラムは、次の関数に書きます.
    function stopBubble(e){
        if(e && e.stopPropagation){
            e.stopPropagation(); //DOM
        }else{
            window.even.cancelBubble=true; //IE
        }
    }

    このstopBubble(e)関数をあなたが望む阻止イベントバブル関数に入れると、イベントバブルを阻止することができます.

    四イベントオブジェクト


    1.DOMイベントオブジェクト現代ブラウザでは、イベントハンドラに対してイベントオブジェクトがパラメータとして渡され、IEブラウザがDOM 0レベルでイベントをバインドする場合、eventはwindowオブジェクトの属性であり、その他の方法ではイベント処理関数のパラメータである.異なるイベントには異なるプロパティとメソッドがありますが、現代のブラウザでは、すべてのイベントオブジェクトに次のプロパティとメソッドがあります.
  • currentTargetプロパティ:イベントハンドラがイベントを処理している要素(すなわち、イベントハンドラを呼び出している要素)であり、これは常にcurrentTargetに等しい.targetプロパティは、実際にイベントがトリガーされた要素である最も具体的なターゲットを指します.
  • <script type="text/javascript"> var outside = document.getElementById("outside"); var inside = document.getElementById("inside"); outside.onclick=function(event){ //  event   alert("I am outside"); alert("this==event.currentTarget? " + (this===event.currentTarget)); //+     === alert("event.target==this? " + (event.target===this)); alert("event.target==inside? " + (event.target===inside)); }; inside.onclick=function(event){ alert("I am inside"); alert("this==event.currentTarget? " + (this===event.currentTarget)); alert("event.target==this? " + (event.target===this)); alert("event.target==inside? "+ (event.target===inside)); }; </script>
  • typeプロパティ:イベントのタイプ
  • preventDefault():イベントがトリガーされたときのデフォルトの動作をブロックします.たとえば、ハイパーリンクをクリックしてurlで指定されたページにジャンプします.このメソッドは、cancelableプロパティがtrueに設定されているイベントのみ使用できます.
  • eventPhaseプロパティ:イベントハンドラが呼び出されたときにどのフェーズにあるか.1はキャプチャフェーズ、2はターゲットオブジェクト、3はバブルフェーズです.

  • eventオブジェクトはイベントハンドラの実行中にのみ存在し、実行が完了すると破棄されます.2.IEにおけるイベントオブジェクトIEにおけるイベントオブジェクトの方式は、イベントを追加する方法に応じていくつかある.DOM 0レベルのメソッドを使用する場合、eventオブジェクトはwindowオブジェクトの属性としてwindowであるべきである.イベントはこのような方法で使用されます.attachEvent()メソッドを使用する場合、eventはイベント処理関数のパラメータとして、もちろんwindowのプロパティとしても使用できます.オブジェクトには、次のプロパティとメソッドがあります.-cancelBubbleプロパティ:デフォルトはfalse、trueに設定するとイベントバブルがキャンセルされます-returnValueプロパティ:デフォルトはtrue、falseに設定するとイベントトリガがキャンセルされるときのデフォルトの動作-src Elementプロパティ:targetと同じ注意:(1)IEでイベントハンドラの役割ドメインに追加する方法で決定され、DOM 0レベルの方法を使用すると、これがプロセッサを呼び出す要素であり、attachEventで指定するとthis=windowになります.したがって、これは常にイベントターゲットに等しいとは思えずeventを用いる.src Elementはイベントターゲット比較保険を指定します.(2)IEはイベントキャプチャをサポートせず,cancelBubbleを使用するとイベントバブルのみがキャンセルされ,stopPropagation()はキャプチャもバブルもキャンセルされる.3.ブラウザにまたがるイベントオブジェクトDOMとIE内のイベントオブジェクトは異なるが、それらには多くの方法と属性が対応している.ここでEventUtilオブジェクトを強化し、ブラウザ間のイベントオブジェクトとイベントハンドラを実現します.
    <script type="text/javascript"> var EventUtil={ addHandler:function(element,type,handler){ if(element.addEventListener){ //DOM2    element.addEventListener(type,handler,false); }else if(element.attachEvent){ //IE   element.attachEvent("on"+type,handler); }else{ //DOM0  element["on"+type]=handler; } }, removeHandler:function(element,type,handler){ if(element.removeEventListener){ element.removeEventListener(type,handler,false); }else if(element.detachEvent){ element.detachEvent("on"+type,handler); }else{ element["on"+type]=null; } }, getEvent:function(event){ //      event  ,IE    DOM0    event undefined  return event? event:window.event; }, getTarget:function(event){ return event.target || event.srcElement; }, preventDefault:function(event){ if(event.preventDefault){ event.preventDefault(); }else{ event.returnValue=false; } }, stopPropagation:function(event){ if(event.stopPropagation){ event.stopPropagation(); }else{ event.cancelBubble=true; } } }; </script>