https://developer.mozilla.org/en/DOM/element.addEventListener で記事を読みましたが、useCapture
属性を理解できません。定義があります:
Trueの場合、useCaptureは、ユーザーがキャプチャを開始したいことを示します。キャプチャの開始後、指定されたタイプのすべてのイベントは、DOMツリーでその下のEventTargetにディスパッチされる前に、登録されたリスナーにディスパッチされます。ツリーを上方向にバブリングしているイベントは、キャプチャを使用するように指定されたリスナーをトリガーしません。
このコードでは、親イベントが子の前にトリガーされるので、その動作を理解できません。ドキュメントオブジェクトのusecaptureがtrueで、子divのusecaptureがfalseに設定され、ドキュメントのusecaptureが追跡されます。
function load() {
document.addEventListener("click", function() {
alert("parent event");
}, true);
document.getElementById("div1").addEventListener("click", function() {
alert("child event");
}, false);
}
<body onload="load()">
<div id="div1">click me</div>
</body>
イベントは、開始時(「キャプチャ」)と終了時(「バブル」)の2つの場合にアクティブにできます。イベントは、定義された順序で実行されます。 4つのイベントリスナーを定義するとします。
window.addEventListener("click", function(){alert(1)}, false);
window.addEventListener("click", function(){alert(2)}, true);
window.addEventListener("click", function(){alert(3)}, false);
window.addEventListener("click", function(){alert(4)}, true);
警告ボックスは次の順序でポップアップ表示されます。
2
(最初に定義され、capture=true
を使用)4
(capture=true
を使用して2番目に定義)1
(capture=false
で最初に定義されたイベント)3
(capture=false
で2番目に定義されたイベント)この図は、キャプチャ/ターゲット/バブルのフェーズを理解するのに非常に役立ちます。 http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html #Events-phases
以下は、リンクから抽出されたコンテンツです。
フェーズ
イベントは、ツリーのルートからこのターゲットノードへのパスに従ってディスパッチされます。その後、ターゲットノードレベルで、またはツリーの上位にあるターゲットの祖先からローカルに処理できます。イベントのディスパッチ(イベント伝播とも呼ばれます)は、3つのフェーズと次の順序で発生します。
ターゲットの祖先は、イベントの最初のディスパッチの前に決定されます。ディスパッチ中にターゲットノードが削除された場合、またはターゲットの祖先が追加または削除された場合、イベントの伝播は常にディスパッチ前に決定されたターゲットノードとターゲットの祖先に基づきます。
一部のイベントは、DOMイベントフローの3つのフェーズを必ずしも完了するとは限りません。イベントは1つまたは2つのフェーズに対してのみ定義できます。例として、この仕様で定義されたイベントは常にキャプチャおよびターゲットフェーズを実行しますが、一部はバブリングフェーズを実行しません(「バブリングイベント」対「非バブリングイベント」。Event.bubbles属性も参照)。
useCapture = true
)vsバブルイベント(useCapture = false
)useCapture
パラメーターは重要ではありません(@bamおよび@ legend80sに感謝)stopPropagation()
はフローを停止します結果:
子どもたちの捕獲
(子供がターゲットであるため、キャプチャとバブルは登録された順にトリガーされます)
var parent = document.getElementById('parent'),
children = document.getElementById('children');
children.addEventListener('click', function (e) {
alert('Children Bubble 1');
// e.stopPropagation();
}, false);
children.addEventListener('click', function (e) {
alert('Children Capture');
// e.stopPropagation();
}, true);
children.addEventListener('click', function (e) {
alert('Children Bubble 2');
// e.stopPropagation();
}, false);
parent.addEventListener('click', function (e) {
alert('Parent Capture');
// e.stopPropagation();
}, true);
parent.addEventListener('click', function (e) {
alert('Parent Bubble');
// e.stopPropagation();
}, false);
<div id="parent">
<div id="children">
Click
</div>
</div>
UseCapture = trueと言うと、イベントはキャプチャフェーズで上から下に実行され、falseの場合、下から上にバブルが実行されます。
コード例:
<div id="div1" style="background:#9595FF">
Outer Div<br />
<div id="div2" style="background:#FFFFFF">
Inner Div
</div>
</div>
JavaScriptコード:
d1 = document.getElementById("div1");
d2 = document.getElementById("div2");
両方がfalseに設定されている場合
d1.addEventListener('click',function(){alert("Div 1")},false);
d2.addEventListener('click',function(){alert("Div 2")},false);
実行:内部Divをクリックすると、アラートは次のように表示されます:Div 2> Div 1
ここで、スクリプトは内部要素から実行されます:Event Bubbling(useCaptureがfalseに設定されています)
div 1はtrueに設定され、div 2はfalseに設定されます
d1.addEventListener('click',function(){alert("Div 1")},true);
d2.addEventListener('click',function(){alert("Div 2")},false);
実行:内部Divをクリックすると、アラートは次のように表示されます:Div 1> Div 2
ここで、スクリプトは祖先/外部要素から実行されます:イベントキャプチャ(useCaptureがtrueに設定されています)
div 1はfalseに設定され、div 2はtrueに設定されます
d1.addEventListener('click',function(){alert("Div 1")},false);
d2.addEventListener('click',function(){alert("Div 2")},true);
実行:内部Divをクリックすると、アラートは次のように表示されます:Div 2> Div 1
ここで、スクリプトは内部要素から実行されます:Event Bubbling(useCaptureがfalseに設定されています)
div 1はtrueに設定され、div 2はtrueに設定されます
d1.addEventListener('click',function(){alert("Div 1")},true);
d2.addEventListener('click',function(){alert("Div 2")},true);
実行:内部Divをクリックすると、アラートは次のように表示されます:Div 1> Div 2
ここで、スクリプトは祖先/外部要素から実行されます。useCaptureがtrueに設定されているため、イベントキャプチャ
すべてはイベントモデルについてです: http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow バブリング段階またはキャプチャ段階でイベントをキャッチできます。あなたの選択。
http://www.quirksmode.org/js/events_order.html をご覧ください-非常に便利です。 。
イベントの3つのフェーズtravelを考えると:
- capture phase:イベントは、ツリーのルートからターゲットノードの直接の親にターゲットの祖先にディスパッチされます。
- ターゲットフェーズ:イベントはターゲットノードにディスパッチされます。
- バブリングフェーズ:イベントは、ターゲットノードの直接の親からツリーのルートまでターゲットの祖先にディスパッチされます。
useCapture
は、イベントtravelがオンになるフェーズを示します。
true
の場合、useCaptureは、ユーザーがキャプチャフェーズのみにイベントリスナーを追加したいことを示します。つまり、このイベントリスナーはターゲット中にトリガーされず、バブリング段階。false
の場合、イベントリスナーはターゲット段階とバブリング段階でのみトリガーされます
ソースは2番目のベストアンサーと同じです。 https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
以下で説明されているDOM
仕様:
https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
次の方法で動作します。
イベントは、ツリーのルート(document
)からターゲットノードへのパスに従ってディスパッチされます。ターゲットノードは、最も深いHTML
要素、つまりevent.targetです。イベントのディスパッチ(イベント伝播とも呼ばれます)は、3つのフェーズと次の順序で発生します。
document
)からターゲットノードの直接の親へ、ターゲットの祖先にディスパッチされます。html
要素にあります。// bubbling handlers, third argument (useCapture) false (default)
document.getElementById('outerBubble').addEventListener('click', () => {
console.log('outerBubble');
}, false)
document.getElementById('innerBubble').addEventListener('click', () => {
console.log('innerBubble');
}, false)
// capturing handlers, third argument (useCapture) true
document.getElementById('outerCapture').addEventListener('click', () => {
console.log('outerCapture');
}, true)
document.getElementById('innerCapture').addEventListener('click', () => {
console.log('innerCapture');
}, true)
div:hover{
color: red;
cursor: pointer;
}
<!-- event bubbling -->
<div id="outerBubble">
<div id="innerBubble">click me to see Bubbling</div>
</div>
<!-- event capturing -->
<div id="outerCapture">
<div id="innerCapture">click me to see Capturing</div>
</div>
上記の例は、イベントバブリングとイベントキャプチャの違いを実際に示しています。 addEventListener
を使用してイベントリスナーを追加する場合、useCaptureという3番目の要素があります。これはboolean
で、true
に設定すると、イベントリスナーはイベントバブリングの代わりにイベントキャプチャを使用できます。
この例では、useCapture引数をfalse
に設定すると、イベントのバブリングが発生することがわかります。最初にターゲットフェーズでイベントが発生し(innerBubbleに記録)、次にイベントバブリングを介して親要素のイベントが発生します(outerBubbleに記録)。
UseCapture引数をtrue
に設定すると、外側の<div>
のイベントが最初に発生することがわかります。これは、イベントがバブリングフェーズではなくキャプチャフェーズで発生するためです。
定義の順序は、アイテムが同じレベルにある場合にのみ重要です。コード内の定義の順序を逆にすると、同じ結果が得られます。
ただし、2つのイベントハンドラーのuseCapture設定を逆にすると、子イベントハンドラーは親のイベントハンドラーの前に応答します。これは、親イベントハンドラーがトリガーされるバブリングフェーズの前のキャプチャフェーズで子イベントハンドラーがトリガーされるためです。
定義の順序に関係なく、両方のイベントハンドラーでuseCaptureをtrueに設定すると、キャプチャ段階で子の前に来るため、親イベントハンドラーが最初にトリガーされます。
逆に、両方のイベントハンドラーでuseCaptureをfalseに設定すると(定義の順序に関係なく)、子イベントハンドラーは、バブリングフェーズで親の前に来るため、最初にトリガーされます。