TIL

이벤트 버블링 & 캡처링 & 위임

세모이 2022. 4. 19. 12:05
반응형

이벤트 버블링 - 한 요소에 이벤트가 발생하면, 이 요소에 할당된 핸들러가 동작하고, 이어서 부모 요소의 핸들러가 동작합니다. 가장 최상단의 조상 요소를 만날 때까지 이 과정이 반복되면서 요소 각각에 할당된 핸들러가 동작

<div class="one">
      첫번째
      <div class="two">
        두번째
        <button class="three">세번째</button>
      </div>
</div>
var divs = document.querySelectorAll('div');
divs.forEach(function(div) {
	div.addEventListener('click', logEvent);
});

function logEvent(event) {
	console.log(event.currentTarget.className);
}

var button = document.querySelector('button');
button.addEventListener('click', logEvent);

//버튼 클릭시
//three -> two -> one

버튼을 클릭 했을 시 <button>에 할당된 onclick 이벤트가 동작 하고 그 상위의 div 이벤트가 순차적으로 일어난다.

왜 버튼만 클릭했을 뿐인데 3개의 이벤트가 발생하는 건가?

  • 브라우저가 이벤트를 감지하는 방식 때문이다.
  • 브라우저는 특정 화면 요소에서 이벤트가 발생했을 때 그 이벤트를 최상위에 있는 화면 요소까지 이벤트를 전파 시킨다.
  • 태그마다 이벤트가 등록되어 있기 때문에 상위 요소로 이벤트가 전달되는 것을 확인 할 수 있고 이벤트가 등록되어 있지 않으면 동작 결과는 달라 질 수 있다.

 

 

이벤트 캡처링 - 이벤트 버블링과 반대 방향으로 진행되는 이벤트 전파 방식

addEventListener의 세번 째 요소를 작성하지 않으면 default 값이 false 인데, false로 설정할 경우 핸들러는 버블링 단계로 설정되고 capture:true로 설정할 경우 핸들러는 캡처링 단계로 설정

var divs = document.querySelectorAll('div');
divs.forEach(function(div) {
	div.addEventListener('click', logEvent,{
    capture:true
});
});

function logEvent(event) {
	console.log(event.currentTarget.className);
}

var button = document.querySelector('button');
button.addEventListener('click', logEvent, {
    capture:true
});

//버튼 클릭시
//one -> two -> three

- event.stopPropagation()

  • 원하는 화면 요소의 이벤트만 작동을 시키고 싶은 때
  • stopPropagation() 함수는 해당 이벤트가 전파되는 것을 막는다.

 

 

이벤트 위임 - 하위 요소에 각각 이벤트를 붙이지 않고 상위 요소에서 하위 요소의 이벤트들을 제어하는 방식

<h1>오늘의 할 일</h1>
    <ul class="itemList">
      <li>
        <input type="checkbox" id="item1" />
        <label for="item1">이벤트 버블링 학습</label>
      </li>
      <li>
        <input type="checkbox" id="item2" />
        <label for="item2">이벤트 캡쳐 학습</label>
      </li>
    </ul>
// 간단한 체크 박스 만들고 체크박스 클릭시 경고창 뜨도록 함
var inputs = document.querySelectorAll('input');
inputs.forEach(function(input) {
	input.addEventListener('click', function(event) {
		alert('clicked');
	});
});

// 새 리스트 아이템을 추가하는 코드
var itemList = document.querySelector('.itemList');

var li = document.createElement('li');
var input = document.createElement('input');
var label = document.createElement('label');
var labelText = document.createTextNode('이벤트 위임 학습');

input.setAttribute('type', 'checkbox');
input.setAttribute('id', 'item3');
label.setAttribute('for', 'item3');
label.appendChild(labelText);
li.appendChild(input);
li.appendChild(label);
itemList.appendChild(li);

새로 추가한 리스트 아이템에는 클릭 이벤트가 정상적으로 동작하지 않는다.

why? 인풋 박스에 이벤트를 추가하는 시점에서는 리스트 아이템은 2개이기 때문에 그럼 추가하는 리스트 아이템은 일일이 이벤트를 달아줘야 하는가?

→ 리스트 아이템이 많아질 수록 이벤트를 다루는게 번거러워 지는데 이걸 해결하는 방법이 이벤트 위임이다.

반응형