이벤트 버블링 및 캡처란 무엇입니까?
이벤트 버블과 캡처의 차이점은 무엇입니까?거품 대 캡처는 언제 사용해야 합니까?
이벤트 버블링과 캡처는 HTML DOM API에서 이벤트를 전파하는 두 가지 방법으로, 이벤트가 다른 요소 내부의 요소에서 발생하며 두 요소 모두 해당 이벤트에 대한 핸들을 등록했습니다.이벤트 전파 모드에 따라 요소가 이벤트를 수신하는 순서가 결정됩니다.
버블링에서는 이벤트가 먼저 가장 안쪽 요소에 의해 캡처되고 처리된 후 외부 요소로 전파됩니다.
캡처에서는 이벤트가 가장 바깥쪽 요소에 의해 먼저 캡처되고 내부 요소로 전파됩니다.
캡처는 전파 순서를 기억하는 데 도움이 되는 "트리클링"이라고도 합니다.
흘러내리다
과거에 Netscape는 이벤트 캡처를 주창했고 Microsoft는 이벤트 버블링을 장려했습니다.둘 다 W3C Document Object Model Events 표준(2000)의 일부입니다.
IE < 9는 이벤트버블링만을 사용하는 반면 IE9+와 모든 주요 브라우저는 둘 다 지원합니다.한편, 복잡한 DOM에서는, 이벤트 버블링의 퍼포먼스가 약간 저하하는 경우가 있습니다.
, 그럼 이렇게 .addEventListener(type, listener, useCapture)
이벤트 핸들러를 버블링 모드(기본값) 또는 캡처 모드로 등록합니다.하려면 세 the the to 、 처 、 음 、 음 、 음 、 음음음 。true
.
예
<div>
<ul>
<li></li>
</ul>
</div>
에서 클릭 합니다.li
★★★★★★ 。
는 """에 됩니다.div
번째 번째 합니다).div
에서, 다음에 발화한다.ul
후 타깃 에는 " " "가"가 됩니다li
.
그에 '버블링 모델'에 됩니다.이벤트는 처음에 에 의해 처리됩니다.li
후, 에 ul
「」를 해 주세요.div
★★★★★★ 。
상세한 것에 대하여는, 을 참조해 주세요.
- QuicksMode의 이벤트 순서
- MDN에서의 addEventListener
- QuicksMode에서 진행되는 이벤트
다음 예에서는 강조 표시된 요소를 클릭하면 이벤트 전파 흐름의 캡처 단계가 먼저 발생하고 버블 단계가 이어지는 것을 확인할 수 있습니다.
var logElement = document.getElementById('log');
function log(msg) {
logElement.innerHTML += ('<p>' + msg + '</p>');
}
function capture() {
log('capture: ' + this.firstChild.nodeValue.trim());
}
function bubble() {
log('bubble: ' + this.firstChild.nodeValue.trim());
}
function clearOutput() {
logElement.innerHTML = "";
}
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', capture, true);
divs[i].addEventListener('click', bubble, false);
}
var clearButton = document.getElementById('clear');
clearButton.addEventListener('click', clearOutput);
p {
line-height: 0;
}
div {
display:inline-block;
padding: 5px;
background: #fff;
border: 1px solid #aaa;
cursor: pointer;
}
div:hover {
border: 1px solid #faa;
background: #fdd;
}
<div>1
<div>2
<div>3
<div>4
<div>5</div>
</div>
</div>
</div>
</div>
<button id="clear">clear output</button>
<section id="log"></section>
JSFiddle의 다른 예.
설명:
quirksmode.org은 이에 대한 좋은 설명을 제공하고 있습니다.요약하면(quirks 모드에서 복사):
이벤트 캡처
이벤트 캡처를 사용하는 경우
| | ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 \ / | | | ------------------------- | | Event CAPTURING | -----------------------------------
element1의 이벤트핸들러가 먼저 기동하고 element2의 이벤트핸들러가 마지막에 기동합니다
이벤트 버블링
이벤트 버블링 사용 시
/ \ ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 | | | | | ------------------------- | | Event BUBBLING | -----------------------------------
element2의 이벤트핸들러가 먼저 기동하고 element1의 이벤트핸들러가 마지막에 기동합니다
뭘 쓸까?
당신이 무엇을 하고 싶은지에 달렸어요.이보다 더 좋을 순 없다.차이점은 이벤트 핸들러의 실행 순서입니다.대부분의 경우 이벤트 핸들러를 버블링 단계에서 해고하는 것이 좋습니다만, 조기에 해고하는 것도 필요할 수 있습니다.
요소 1과 요소 2가 두 개 있는 경우.요소 2는 요소 1 안에 있으며, 두 요소 모두 이벤트 핸들러를 연결합니다(예: onClick).이제 요소 2를 클릭하면 두 요소에 대한 eventHandler가 실행됩니다.여기서 문제는 이벤트가 어떤 순서로 실행되느냐입니다.요소 1에 연결된 이벤트가 먼저 실행되는 경우 이벤트 캡처라고 하며 요소 2에 연결된 이벤트가 먼저 실행되는 경우 이벤트 버블링이라고 합니다.W3C에 따라 이벤트는 캡처 단계에서 시작하여 타겟에 도달한 후 다시 엘리먼트로 돌아와 버블을 시작합니다.
캡처 및 버블링 상태는 addEventListener 메서드의 useCapture 파라미터로 알 수 있습니다.
eventTarget.addEventListener(type, listener, [,useCapture]);
기본적으로 useCapture는 false입니다.그것은 거품이 일고 있다는 것을 의미한다.
var div1 = document.querySelector("#div1");
var div2 = document.querySelector("#div2");
div1.addEventListener("click", function (event) {
alert("you clicked on div 1");
}, true);
div2.addEventListener("click", function (event) {
alert("you clicked on div 2");
}, false);
#div1{
background-color:red;
padding: 24px;
}
#div2{
background-color:green;
}
<div id="div1">
div 1
<div id="div2">
div 2
</div>
</div>
true와 false를 바꿔보세요.
저는 javascript.info에서 이 튜토리얼을 통해 이 주제를 매우 명확하게 설명할 수 있다는 것을 알았습니다.그리고 마지막 3점 요약은 정말 중요한 요점을 말하고 있다.여기서 인용하겠습니다.
- 이벤트는 먼저 가장 깊은 타겟까지 캡처된 후 버블 상태가 됩니다.IE<9에서는 버블만 발생합니다.
- 하지만 예외는 없습니다.
addEventListener
인수인 '''를 붙입니다.true
캡쳐 스테이지에서 이벤트를 볼 수 있는 유일한 방법입니다.- 버블링은 블캡캡/캡 bub bub bub bub bub bub bub bub로 할 수 .
event.cancelBubble=true
(IE) ★event.stopPropagation()
참の참
이벤트가 타깃인지 다른 곳에서 왔는지 알려주는 속성도 있으며 브라우저에 의해 완전히 지원됩니다.
승인된 답변에서 이미 훌륭한 스니펫을 확장하면 다음과 같이 출력됩니다.eventPhase
소유물
var logElement = document.getElementById('log');
function log(msg) {
if (logElement.innerHTML == "<p>No logs</p>")
logElement.innerHTML = "";
logElement.innerHTML += ('<p>' + msg + '</p>');
}
function humanizeEvent(eventPhase){
switch(eventPhase){
case 1: //Event.CAPTURING_PHASE
return "Event is being propagated through the target's ancestor objects";
case 2: //Event.AT_TARGET
return "The event has arrived at the event's target";
case 3: //Event.BUBBLING_PHASE
return "The event is propagating back up through the target's ancestors in reverse order";
}
}
function capture(e) {
log('capture: ' + this.firstChild.nodeValue.trim() + "; " +
humanizeEvent(e.eventPhase));
}
function bubble(e) {
log('bubble: ' + this.firstChild.nodeValue.trim() + "; " +
humanizeEvent(e.eventPhase));
}
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', capture, true);
divs[i].addEventListener('click', bubble, false);
}
p {
line-height: 0;
}
div {
display:inline-block;
padding: 5px;
background: #fff;
border: 1px solid #aaa;
cursor: pointer;
}
div:hover {
border: 1px solid #faa;
background: #fdd;
}
<div>1
<div>2
<div>3
<div>4
<div>5</div>
</div>
</div>
</div>
</div>
<button onclick="document.getElementById('log').innerHTML = '<p>No logs</p>';">Clear logs</button>
<section id="log"></section>
DOM 이벤트는 이벤트 전파의 3가지 단계를 설명합니다.캡처 단계 – 이벤트는 요소까지 내려갑니다.Target phase – 이벤트가 Target 요소에 도달했습니다.버블링 단계 – 이벤트는 요소에서 버블링됩니다.
부글부글 끓다
Event propagate to the upto root element is **BUBBLING**.
캡처
Event propagate from body(root) element to eventTriggered Element is **CAPTURING**.
앞서 설명한 바와 같이 버블링과 캡처는 일부 중첩된 요소가 특정 이벤트를 수신하는 순서를 나타냅니다.
가장 안쪽의 요소는 뭔가 이상한 것으로 보일 수 있다는 것을 지적하고 싶었습니다.실제로 이 경우 이벤트청취자가 추가되는 순서는 중요합니다.
다음 예제에서는 캡처:div2
버블링보다 먼저 실행됩니다.div4
캡처보다 먼저 실행됩니다.
function addClickListener (msg, num, type) {
document.querySelector("#div" + num)
.addEventListener("click", () => alert(msg + num), type);
}
bubble = (num) => addClickListener("bubble ", num, false);
capture = (num) => addClickListener("capture ", num, true);
// first capture then bubble
capture(1);
capture(2);
bubble(2);
bubble(1);
// try reverse order
bubble(3);
bubble(4);
capture(4);
capture(3);
#div1, #div2, #div3, #div4 {
border: solid 1px;
padding: 3px;
margin: 3px;
}
<div id="div1">
div 1
<div id="div2">
div 2
</div>
</div>
<div id="div3">
div 3
<div id="div4">
div 4
</div>
</div>
편집: 이러한 동작은 브라우저에 따라 다를 수 있습니다(예를 들어 현재 Firefox에서는 발생하지만 Chrome 및 Edge에서는 발생하지 않습니다).그러나 나는 그것을 알아야 한다고 생각한다.
언급URL : https://stackoverflow.com/questions/4616694/what-is-event-bubbling-and-capturing
'programing' 카테고리의 다른 글
OS X 10.7에서 Mysql 명령을 찾을 수 없습니다. (0) | 2023.01.24 |
---|---|
C/C++에서 libcurl을 사용하여 파일 다운로드 (0) | 2023.01.24 |
MySQL에 여러 개의 열 외부 키가 있습니까? (0) | 2023.01.24 |
mysqldump에 의해 생성되는 방대한 라인 길이에 대처하는 방법 (0) | 2023.01.24 |
MySQL 데이터베이스를 메모리에서 완전히 실행하려면 어떻게 해야 합니까? (0) | 2023.01.24 |