記事のディレクトリ
EventTargetイベントターゲットの検索方法(バブリングとキャプチャ)
バブリングとキャプチャ:
-
バブリングイベント
- イベントのデフォルトは、ボトムアップのバブリング実行メソッドです。例としてクリックイベントを取り上げます。子要素をクリックすると、親要素以上のクリックイベントもトリガーできます。イベントの実行順序は下から上で、バブリングイベントです。
-
キャプチャイベント:
- もちろん、トップダウンのキャプチャ方法もあります。クリックイベントを例にとると、子要素がクリックイベントにバインドされている場合、子要素をクリックすると、親要素と上記の要素にバインドされたクリックイベントも実行されます。イベントの実行シーケンスは、キャプチャイベントである上から下です。
addEventListener(type、listener、useCapture)簡単な分析:
- タイプ:イベントタイプ
- リスナー:イベントリスナー処理機能
- useCapture:イベント検索方法を設定します
- false、バブリングイベント(デフォルト値)
- true、キャプチャイベント
パラメータuseCaptureの詳細な説明:
useCaptureの値は、イベントターゲットの検索方法がキャプチャであるかバブリングであるかを決定します。
要素が別の要素とネストされていて、両方の要素が同じイベントに登録されている場合。2つの要素に異なるuseCapture値(バブリングとキャプチャ)を設定するため、バブリングとキャプチャは2つの異なるイベントルックアップメソッドです。イベントルックアップメソッドは、要素がイベントを受信する順序を決定します。
バブリングとキャプチャのシーケンス:
- 図から、イベントが最初にキャプチャされ、次にイベントがバブリングされていることがわかります。イベントのキャプチャは上から下に、イベントのバブリングは下から上に行われます。
- キャプチャのプロセスは非特定から特定へ、バブリングは特定から非特定へです。
- ですが最初にキャプチャする、ただし、バブリングイベントがデフォルトの配信方法です。
コードデモ:
<body>
<div id="div1">
这是div1
<div id="div2">
这是div2
<div id="div3">这是div3</div>
</div>
</div>
<script>
let div1 = document.getElementById('div1');
let div2 = document.getElementById('div2');
let div3 = document.getElementById('div3');
div1.addEventListener('click',function(){
console.log("这是div1的点击事件");
},false);
div2.addEventListener('click',function(){
console.log("这是div2的点击事件");
},false);
div3.addEventListener('click',function(){
console.log("这是div3的点击事件");
},false);
</script>
</body>
次のようにコンソールの結果からわかるように、div3をクリックすると、ここで発生したのはバブリングイベントです。
それでもdiv3をクリックすると、div1.addEventListener
3番目のパラメーターがtrueに変更されます。次のように、div1が最初に実行され、キャプチャがバブリングよりも優先されることを示しています。
上記は、イベントターゲットを見つけるために使用する2つのメカニズムです。バブル対キャプチャー理解。
イベントプロキシメカニズム
イベントバブリングを使用して、イベントプロキシメカニズムを完成させます。
<ul>
<li>列表1</li>
<li>列表2</li>
</ul>
li
クリックイベントを上記のリストのすべてのアイテムにバインドする場合、クリックしてliのデータを取得します。通常は、要素をトラバースしてクリックイベントをバインドするために使用します。
let lis = document.querySelectorAll('li');
for (let i = 0; i < lis.length; i++) {
lis[i].addEventListener('click', function () {
console.log(this.innerHTML);
});
}
ただし、要素が多すぎると、この操作がコードのパフォーマンスに影響するため、バブリングメカニズムを使用してイベントプロキシを完成させることができます。イベントを親要素にバインドすることです。
イベントオブジェクトに関する知識ポイント:
EventTarget.addEventListener(type,listener,useCapture);
イベントをバインドすると、イベントリスナー処理関数(リスナー)の最初のパラメーターは次のようになります。イベントオブジェクト。イベントオブジェクトには、イベントソース、イベントID、イベントタイプ、イベントバインディング要素、イベントがトリガーされたときのクリックの場所など、イベントに関する詳細情報が含まれています。
<body>
<ul>
<li>列表1</li>
<li>列表2</li>
</ul>
<script>
let ul = document.querySelector('ul');
//我们可以通过事件对象e中的target属性可以访问到事件源(也就事件的触发元素)
ul.addEventListener('click',function(e){
console.log(e.target.innerHTML);
},false);
</script>
</body>
リスト1とリスト2をクリックします。
概要:上記のコードにより、e.targetがイベント委任を実装できることがわかります。イベント委任は、イベントバブリング(またはイベントキャプチャ)を通じて親要素にイベントを追加することであり、e.targetはアクセスできます。トリガー。イベントの要素(イベントソース)。したがって、e.targetはバブリングの開始点であり、e.targetはキャプチャの終了です。
e.targetとe.currentTargetの違い:
- e.targetは、イベントリスナーをトリガーするオブジェクト(イベントソース)を指します。
- e.currentTargetは、イベントをリッスンするオブジェクト(イベントがバインドされているdom要素)を指します。
バブリングとキャプチャを防止します
なぜバブリングやキャプチャを停止するのですか?
(当面はここでイベントプロキシを省略します。)現在の要素がクリックされると、イベントはバブリング方式で配信されます。親要素が同じイベントにバインドされている場合、バブリング配信によってトリガーされます。 。同じキャプチャプロセスで、現在の要素にバインドされている同じイベントの親もトリガーされます。トリガーシーケンスのみが異なります。
イベントエージェントは通常、バブリングを使用します。もちろん、シーケンスの問題はイベントのキャプチャにのみ影響するため、バブリングを防止してもイベントエージェントには影響しません。そのため、バブリングはイベントエージェントメカニズムの実装に使用されます。
バブリングやキャプチャを防ぐ方法
ここでは互換性の問題は考慮していません。互換性は近い将来解決できると思います。
バブリングw3c勧告を停止するメソッドは、event.stopPropagation()です。名前が示すように、伝播を停止します。これは、イベントオブジェクト(イベント)のメソッドです。このメソッドは、ターゲット要素がバブリング(またはキャプチャ)するのを防ぎます。
event.stopPropagation()はバブリングを防ぎます:
<body>
<div id="div1">
这是div1
<div id="div2">
这是div2
<div id="div3">这是div3</div>
</div>
</div>
<script>
let div1 = document.getElementById('div1');
let div2 = document.getElementById('div2');
let div3 = document.getElementById('div3');
div1.onclick = function (e) {
alert('div1');
}
div2.onclick = function (e) {
e.stopPropagation();
alert('div2');
}
div3.onclick = function (e) {
alert('div3');
}
</script>
</body>
上記のコードはすべてデフォルトでバブリングイベントです。div3をクリックすると、「div3」と「div2」が順番にポップアップします。「div1」がポップアップしないのはなぜですか?これは、e.stopPropagation();がターゲット要素がバブルを継続して上位レベルに到達するイベント。e.topPropagationが各クリックイベントに追加された場合、複数のポップアップは表示されません。
event.stopPropagation()はキャプチャを防ぎます:
<body>
<div id="div1">
这是div1
<div id="div2">
这是div2
<div id="div3">这是div3</div>
</div>
</div>
<script>
let div1 = document.getElementById('div1');
let div2 = document.getElementById('div2');
let div3 = document.getElementById('div3');
div1.addEventListener('click',function(e){
console.log('div1');
},true);
div2.addEventListener('click',function(e){
console.log('div2');
e.stopPropagation();
},true);
div3.addEventListener('click',function(e){
console.log('div3');
},true);
</script>
</body>
div2をクリックすると、「div1」と「div2」が順番にポップアップ表示されます。これは、div2イベントでe.stopPropagation()を設定し、ターゲット要素をブロックしたイベントが引き続きキャプチャされるためです。
event.target == event.currentTarget:
div.addEventListener('click',function(e){
if(event.target == event.currentTarget){
//需要执行的代码
}
});
この方法はあまり説明する必要はありませんが、上記の内容を理解すれば、この方法も理解できます。
使用する理由addEventListener()
上記のコードから、addEventListener()
次の利点があることを確認するのは難しくありません(以下はMDNの元の単語です)。
addEventListener()
これは、W3CDOM仕様で提供されているイベントリスナーを登録するためのメソッドです。その利点は次のとおりです。
- これにより、複数のリスナーをイベントに登録できます。特に、AJAXライブラリ、JavaScriptモジュール、またはサードパーティのライブラリ/プラグインを必要とするその他のコードを使用する場合。
listener
トリガーステージを制御するためのより洗練された手段を提供します。(つまり、キャプチャするかバブルするかを選択できます)。- HTML要素だけでなく、すべてのDOM要素に有効です。
デフォルトのイベントをキャンセルする
event.preventDefault()
デフォルトのイベントはを参照するデフォルトの動作でラベル<a href="">
、<input type="submit">
など飛び降りまたはクリックして提出することができますラベル、と。クリックイベントをこのタイプのラベルにバインドし、イベントオブジェクトのpreventDefault()メソッドを設定して、デフォルトイベントが発生しないようにします。
<body>
<a href="https://www.baidu.com">点击跳转</a>
<script>
let a = document.querySelector('a');
addEventListener('click',function(e){
e.preventDefault();
})
</script>
</body>
したがって、ラベルにデフォルトイベントがあるかどうかを確認し、イベントオブジェクトのキャンセル可能なプロパティを出力し、イベントの実行を通じてe.cancelableの結果を知るにはどうすればよいですか。falseの場合、デフォルトイベントがあることを意味し、trueはそうではありません。
falseを返します。
イベント実行機能で設定falseを返すデフォルトのイベントをキャンセルしますが、この方法は一般的には使用されません。
希望大家能关注我的公众号,我会继续分享更多前端实用技术
。