[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 단계와 다음 순서로 발생합니다.

  1. 캡처 단계 : 이벤트는 트리의 루트에서 대상 노드의 직접 상위로 대상의 조상에 전달됩니다.
  2. 대상 단계 : 이벤트가 대상 노드로 전달됩니다.
  3. 버블 링 단계 : 이벤트가 대상 노드의 직접 상위에서 트리의 루트로 대상의 상위 항목으로 전달됩니다.

DOM 이벤트 흐름을 사용하여 DOM 트리에 전달 된 이벤트의 그래픽 표현

대상의 조상은 이벤트가 처음 전달되기 전에 결정됩니다. 디스패치 중에 대상 노드가 제거되거나 대상의 조상이 추가 또는 제거되면, 이벤트 전파는 항상 대상 노드와 디스패치 전에 결정된 대상의 조상을 기반으로합니다.

일부 이벤트는 DOM 이벤트 흐름의 3 단계를 반드시 수행 할 필요는 없습니다. 예를 들어, 이벤트는 1 단계 또는 2 단계에 대해서만 정의 될 수 있습니다. 예를 들어,이 사양에 정의 된 이벤트는 항상 캡처 및 대상 단계를 수행하지만 일부는 버블 링 단계를 수행하지 않습니다 ( “버블 링 이벤트”대 “비 버블 링 이벤트”, Event.bubbles 속성 참조).


답변

캡처 이벤트 ( useCapture = true) vs 버블 이벤트 ( useCapture = false)

MDN 참조

  • 캡처 이벤트는 버블 이벤트 전에 발송됩니다
  • 이벤트 전파 순서는
    1. 부모 캡처
    2. 어린이 캡처
    3. 대상 캡처 및 대상 버블
      • 그들이 등록 된 순서대로
      • 요소가 이벤트의 대상인 경우 useCapture매개 변수는 중요하지 않습니다 (감사합니다 @bam 및 @ legend80s).
    4. 어린이 버블
    5. 부모 버블
  • stopPropagation() 흐름을 막을 것이다

캡처 흐름 사용

데모

결과:

  1. 부모 캡처
  2. 대상 버블 1

    (Capture 및 Bubble of Target이 등록 된 순서대로 트리거되므로 Bubble 이벤트는 Capture 이벤트 전에 트리거됩니다)

  3. 대상 캡처

  4. 대상 버블 2
  5. 부모 버블
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 단계와 다음 순서로 발생합니다.

  1. 캡처 단계 : 이벤트는 트리의 루트 ( document)에서 대상 노드의 직접 상위로 대상의 상위 항목으로 전달됩니다.
  2. 대상 단계 : 이벤트가 대상 노드로 전달됩니다. 목표 단계는 항상 html이벤트가 분리 된 가장 깊은 요소에 있습니다.
  3. 버블 링 단계 : 이벤트가 대상 노드의 직접 상위에서 트리의 루트로 대상의 상위 항목으로 전달됩니다.

이벤트 버블 링, 이벤트 캡처, 이벤트 대상

예:

// 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>

위의 예는 실제로 이벤트 버블 링과 이벤트 캡처의 차이점을 보여줍니다. 로 이벤트 리스너를 추가 할 때 addEventListeneruseCapture라는 세 번째 요소가 있습니다. 이것은 이벤트 리스너가 이벤트 버블 링 대신 이벤트 캡처를 사용할 수 있도록 boolean설정된 경우입니다 true.

예제에서 useCapture 인수를 설정하면 false이벤트 버블 링이 발생 함을 알 수 있습니다. 먼저 대상 단계에서 이벤트가 시작되고 (innerBubble 로그) 이벤트 버블 링을 통해 상위 요소의 이벤트가 시작됩니다 (outerBubble 로그).

useCapture 인수를 설정하면 true외부의 이벤트 <div>가 먼저 시작됩니다. 이벤트가 버블 링 단계가 아니라 캡처 단계에서 시작 되었기 때문입니다.