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ノードと記す
まとめてみると、
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」など)を付けることに注意してください.