[javascript] addEventListener에서 useCapture 매개 변수를 이해할 수 없습니다.
https://developer.mozilla.org/en/DOM/element.addEventListener 에서 기사를 읽었 지만 useCapture
속성 을 이해할 수 없습니다 . 정의는 다음과 같습니다.
true 인 경우, useCapture는 사용자가 캡처를 시작하려고 함을 나타냅니다. 캡처를 시작하면 지정된 유형의 모든 이벤트가 등록 된 리스너로 전달되고 DOM 트리에서 그 아래의 EventTarget으로 전달됩니다. 트리를 통해 위로 버블 링하는 이벤트는 캡처를 사용하도록 지정된 리스너를 트리거하지 않습니다.
이 코드에서 부모 이벤트는 자식보다 먼저 트리거되므로 해당 동작을 이해할 수 없습니다.
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>
답변
이벤트는 시작 ( “캡처”)과 끝 ( “버블”)의 두 경우에 활성화 될 수 있습니다. 이벤트는 정의 된 순서대로 실행됩니다. 다음과 같이 4 개의 이벤트 리스너를 정의하십시오.
window.addEventListener("click", function(){console.log(1)}, false);
window.addEventListener("click", function(){console.log(2)}, true);
window.addEventListener("click", function(){console.log(3)}, false);
window.addEventListener("click", function(){console.log(4)}, true);
로그 메시지는 다음 순서로 나타납니다.
2
(먼저 정의capture=true
)4
(을 사용하여 두 번째로 정의 됨capture=true
)1
(와 함께 처음 정의 된 이벤트capture=false
)3
(와 함께 정의 된 두 번째 이벤트capture=false
)
답변
이 다이어그램은 캡처 / 대상 / 버블 단계를 이해하는 데 매우 유용합니다.
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()
흐름을 막을 것이다
데모
결과:
- 부모 캡처
-
대상 버블 1
(Capture 및 Bubble of Target이 등록 된 순서대로 트리거되므로 Bubble 이벤트는 Capture 이벤트 전에 트리거됩니다)
-
대상 캡처
- 대상 버블 2
- 부모 버블
var parent = document.getElementById('parent'),
target = document.getElementById('target');
target.addEventListener('click', function (e) {
console.log('Target Bubble 1');
// e.stopPropagation();
}, false);
target.addEventListener('click', function (e) {
console.log('Target Capture');
// e.stopPropagation();
}, true);
target.addEventListener('click', function (e) {
console.log('Target Bubble 2');
// e.stopPropagation();
}, false);
parent.addEventListener('click', function (e) {
console.log('Parent Capture');
// e.stopPropagation();
}, true);
parent.addEventListener('click', function (e) {
console.log('Parent Bubble');
// e.stopPropagation();
}, false);
<div id="parent">
<button id="target" style="padding: 1em 0.8em;">
Trigger event
</button>
</div>
답변
useCapture = true라고 말하면 이벤트가 캡처 단계에서 위에서 아래로 실행됩니다. false이면 아래에서 위로 버블을 수행합니다.
답변
이벤트 모델에 관한 모든 것 : http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow
버블 링 단계 또는 캡처 단계에서 이벤트를 잡을 수 있습니다. 당신의 선택. http://www.quirksmode.org/js/events_order.html을
살펴보십시오 . 매우 유용합니다.
답변
코드 예 :
<div id="div1" style="background:#9595FF">
Outer Div<br />
<div id="div2" style="background:#FFFFFF">
Inner Div
</div>
</div>
자바 스크립트 코드 :
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);
실행 : Inner Div를 클릭하면 경고가 Div 2> Div 1로 표시됩니다.
여기서 스크립트는 내부 요소에서 실행됩니다. 이벤트 버블 링 (useCapture가 false로 설정 됨)
div 1이 true로 설정되고 div 2가 false로 설정되었습니다.
d1.addEventListener('click',function(){alert("Div 1")},true);
d2.addEventListener('click',function(){alert("Div 2")},false);
실행 : Inner 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);
실행 : Inner Div를 클릭하면 경고가 Div 2> Div 1로 표시됩니다.
여기서 스크립트는 내부 요소에서 실행됩니다. 이벤트 버블 링 (useCapture가 false로 설정 됨)
div 1이 true로 설정되고 div 2가 true로 설정되었습니다.
d1.addEventListener('click',function(){alert("Div 1")},true);
d2.addEventListener('click',function(){alert("Div 2")},true);
실행 : Inner Div를 클릭하면 경고가 Div 1> Div 2로 표시됩니다.
여기서 스크립트는 조상 / 외부 요소에서 실행됩니다. useCapture가 true로 설정된 이후의 이벤트 캡처
답변
요약:
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라는 세 번째 요소가 있습니다. 이것은 이벤트 리스너가 이벤트 버블 링 대신 이벤트 캡처를 사용할 수 있도록 boolean
설정된 경우입니다 true
.
예제에서 useCapture 인수를 설정하면 false
이벤트 버블 링이 발생 함을 알 수 있습니다. 먼저 대상 단계에서 이벤트가 시작되고 (innerBubble 로그) 이벤트 버블 링을 통해 상위 요소의 이벤트가 시작됩니다 (outerBubble 로그).
useCapture 인수를 설정하면 true
외부의 이벤트 <div>
가 먼저 시작됩니다. 이벤트가 버블 링 단계가 아니라 캡처 단계에서 시작 되었기 때문입니다.