Event Capture, Propagation, Bubbling and Once

<div class="one">
    <div class="two">
        <div class="three"></div>
    </div>
</div>이렇게 화면이 구성된 페이지가 있다. one이 가장 바깥 안쪽으로 들어 갈수록 two - three로 구성되어 있다.
Bubbling
const divs = document.querySelectorAll('div');
function logText(e) {
  console.log(this.classList.value);
}
divs.forEach(div => div.addEventListener('click', logText));  
//div.two를 클릭할 경우 console창엔
//two
//one 
//div.three를 클릭할 경우
//three
//two
//oneconsole.log를 this로 바꾸고 div.three를 클릭한다면?
const divs = document.querySelectorAll('div');
function logText(e) {
  console.log(this);
}
divs.forEach(div => div.addEventListener('click', logText));  
//console 창엔
//<div class="three"></div>
//<div class="two"></div>
//<div class="one"></div>그럼 console 창에 차례대로 나온다.
여러개가 내포된 요소를 클릭하는 경우 그의 부모요소 DOM까지 클릭 되는 현상을 볼 수 있다.
Capture
javascript가 어떻게 일하는지 보자.
- modern browsers는 capture라고 불리는 것을 한다. 
- element를 클릭하면 그것은 위에서 아래로 흘러내린다. - 브라우저는 "너 body도 클릭하고, one도 클릭하고 two도 클릭하고 three도 클릭했네" 하고 인식한다. 
- 실제로 위에서 아래로 내려가다가, 모든 이벤트를 내가 클릭한 곳에 "captures" 를 하고 보관한다. 
- 하지만 이벤트는 실행되지 않는다. 
- 그럼 이제 클릭한 곳에서 "bubble Up"이 일어난다. 
 
- 그말은 즉 아래에서 위로 이벤트 트리거가 일어난다. 
- 브라우저는 "좋아 우리가 알아낸 지금까지 너가 클릭한 모든 것들을 시작할께" 라고 말한다. 
- three -> two -> one -> body 까지! 
addEventListener의 3번째 option을 사용하자
divs.forEach(div => div.addEventListener('click', logText, {
  //위에서 아래로 흐르는 기능을 사용한다는 거다.
  capture: true
}));false로 바꿔주자.
divs.forEach(div => div.addEventListener('click', logText, {
  //위에서 아래로 흐르는 기능을 사용한다는 거다.
  capture: false
}));Stop Propagation
또 한가지 stop propagation이라 불리는걸 해줘야 한다.
만약 가장 안쪽에 있는걸 클릭한다면, 이벤트가 trigger 된다. parent와 그것의 parent 모두가.
함수를 수정한다.
function logText(e) {
  console.log(this.classList.value);
  e.stopPropagation(); //stop bubbling! 
}bubbling 해주는걸 멈추어 준다. 나는 사실 하나만 클릭했어 라는 뜻이 될 수 있다.'ㅁ' 그럼 내가 본래 원하던 하나를 클릭하게 된다!
capture: true and stopPropagation()
function logText(e) {
  console.log(this.classList.value);
  e.stopPropagation(); // stop bubbling!
  // console.log(this);
}
divs.forEach(div => div.addEventListener('click', logText, {
  capture: true
}));
//console에
//one만 뜬다.왜냐면 capture가 내려갈 때 one에 도착했을 때 stopPropagation이 일어난다. 더이상 내려가지 못하는 것이다.'ㅁ'/
Once
이벤트가 딱 한번만 일어나도록 해준다.
function logText(e) {
    console.log(this.classList.value);
    // e.stopPropagation(); // stop bubbling!
    // console.log(this);
}
divs.forEach(div => div.addEventListener('click', logText, {
    capture: false,
    once: true
}));once를 쓰면 이벤트가 실행되고 그것은 unbind가 된다. unbind는 removeEventListener 로 생각하면 된다.
- 이벤트가 실행되고 once로 인하여 
- addEventListener는 unbind가 된다. 
div요소 각 한번씩 이벤트가 실행될 수 있다.
Example 2
html
<button></button>js
button.addEventListener('click', () => {
    console.log('Click!!!');
}, {
    once: true
});이벤트는 정말 딱 한번만 실행된다!
Last updated
Was this helpful?