2013-08-07 2 views
4

JavaScript의 addEventListener()에서 useCapture 매개 변수를 이해하려고합니다.addEventListener의 useCapture가 이상하게 동작합니다.

<div id="wrapper"> 
    <button id="button">Click me</button> 
</div> 

가 여기 내 자바 스크립트입니다 : 여기 내 HTML의

document.getElementById('wrapper').addEventListener('click', function() { console.log('Wrapper capture'); }, true); 
document.getElementById('wrapper').addEventListener('click', function() { console.log('Wrapper bubble'); }, false); 
document.getElementById('button').addEventListener('click', function() { console.log('Button bubble'); }, false); 
document.getElementById('button').addEventListener('click', function() { console.log('Button capture'); }, true); 

지금, 나는 Wrapper capture, Button capture, Button bubble, Button bubble 될 수있는 순서를 예상했다. 놀랍게도, 내 결과는 다음과 같습니다.

Wrapper capture 
Button bubble 
Button capture 
Wrapper bubble 

두 버튼 핸들러가 겹 칩니 까? 다른 브라우저에서도 테스트했지만 크롬, 파이어 폭스, IE10은 모두 같은 동작을 보입니다. 나는 이것에 약간 당황 스럽다. The MDN, QuirksMode.orgthe spec은 분명히 서로 다른 단계를 설명하고 캡처 단계가 버블 링 단계보다 앞선 것입니다. 내 작은 실험 결과로 Button capture 전에 Button bubble 처리기가 호출되는 이유는 무엇입니까?

여기에 무슨 일이 일어나고 있는지의 바이올린입니다 : http://jsfiddle.net/Tr7G6/2


// 업데이트 그것은 핸들러가 문제가 부착의 순서를 보인다.

document.getElementById('wrapper').addEventListener('click', function() { console.log('Wrapper capture'); }, true); 
document.getElementById('wrapper').addEventListener('click', function() { console.log('Wrapper bubble'); }, false); 
document.getElementById('button').addEventListener('click', function() { console.log('Button capture'); }, true); 
document.getElementById('button').addEventListener('click', function() { console.log('Button bubble'); }, false); 

첫 번째와 버블 초를 캡처 할 바인딩은 예상대로 크로스 브라우저를 출력합니다. 그러나 이것은 바보입니다. 이 주문은 왜 중요합니까?

답변

1

버블 링/캡처는 이벤트가 해당 요소에서 직접 트리거되는 경우가 아니라 (해당 이벤트가 W3C 이벤트 모델의 "대상 단계"일 때) 이벤트가 버블 링/캡처 될 때만 관련이 있습니다. <button>에있는 click 이벤트의 경우 "버블"또는 "캡처"가없는 경우 이벤트는 추가 된 순서대로 처리됩니다. 당신이 당신의 "래퍼"에 청취자의 순서를 반대로 래퍼 요소 (안 버튼) 같은 동작을 확인할 것 클릭한다면

예를 들어, (거품 먼저 해고) :

// 1. "Wrapper Bubble" 2. "Wrapper Capture" 
document.getElementById('wrapper').addEventListener('click', function() { console.log('Wrapper bubble'); }, false); 
document.getElementById('wrapper').addEventListener('click', function() { console.log('Wrapper capture'); }, true); 

그러나 동일한 순서 (캡처하기 전에 버블 링)를 사용하고 button을 클릭하면 버블 링 전에 캡처가 실행됩니다. 이는 "클릭"이벤트가 button에서 트리거되고 "끓어 오르는"(일반적인 이벤트 흐름) 전에 dom을 통해 "캡처 다운"되기 때문입니다.

이 내용을 명확하게 설명하는 데 도움이 될 JSBIN을 만들었습니다 (단, 혼동을 줄 수 있음). "주문한"버튼/div는 첫 번째 스 니펫의 순서를 시작하고 "정렬되지 않은"버튼과 div는 두 번째 순서를 사용합니다.

자세한 내용은 this SO 대답 및 W3C Event Flow 설명서, 특히 Target Phase을 참조하십시오.

+1

"그냥 같은 요소에 있기 때문에"함께 전달 된 우선 순위를 무시하기로 결정했습니다. 스펙에서 리터럴 텍스트를 찾을 수는 없지만,이 동작을 따르는 사용자의 설명과 크로스 브라우저 구현을 고려할 때 사실이어야합니다! 감사 :) –

관련 문제