1. javascript 질문과 답안 (4)

2023. 1. 16. 22:36기술면접 준비

728x90
반응형

이벤트 버블링과 캡처링에 대해 설명해주세요.

 

1. 이벤트 버블링(Event Bubbling)

이벤트 버블링이란 한 요소에 이벤트가 발생하면 이 요소에 할당된 핸들러가 동작하고, 이어서 부모 요소의 핸들러가 동작하고 최상단의 부모 요소를 만날 때까지 반복되면서 핸들러가 동작하는 현상을 말한다.

버블링 예제 코드를 보자.

 <body>
    <div class="DIV1">
      DIV1
      <div class="DIV2">
        DIV2
        <div class="DIV3">DIV3</div>
      </div>
    </div>
  </body>
const divs = document.querySelectorAll("div");

const clickEvent = (e) => {
  console.log(e.currentTarget.className);
};

divs.forEach((div) => {
  div.addEventListener("click", clickEvent);
});

div를 클릭하면 해당하는 클래스의 이름이 콘솔로 출력되는 코드이다. 자바스크립트는 기본적으로 버블링이 발생하기 때문에 <div class="DIV3">DIV3</div>를 클릭한다면 콘솔에는 DIV3, DIV2, DIV1이 순서대로 출력이 될 것이다.

<div class="DIV3">DIV3</div> 를 클릭하면 할당되어 있는 이벤트가 발생하고 다음에는 바깥의 div 태그에 할당된 이벤트가 발생하고 document 객체를 만날 때까지 이벤트가 전파된다.

2. 이벤트 캡처링(Event Capturing)

캡처링은 버블링과는 반대로 최상위 태그에서 해당 태그를 찾아 내려간다.

캡처링은 잘 사용되지는 않지만 어떻게 코드로 구현할 수 있는지 보자.

const divs = document.querySelectorAll("div");

const clickEvent = (e) => {
  console.log(e.currentTarget.className);
};

divs.forEach((div) => {
  div.addEventListener("click", clickEvent, { capture: true });
});

addEventListener 의 옵션 객체에 { capture: true } 또는 true 를 설정해주면 캡처링을 구현할 수 있다.

<div class="DIV3">DIV3</div>를 클릭한다면 위에서부터 찾아 내려오기 때문에 콘솔에는 DIV1, DIV2, DIV3이 순서대로 찍힐 것이다.

 

3. 이벤트 전파 막기

버블링은 해당 타깃에서 document 객체를 만날 때까지 핸들러가 모두 호출되는데 코드를 작성하다보면 원하는 타깃에서만 이벤트를 발생하게 하고 싶을때가 있다.

그럴 때에는 event.stopPropagation() 을 사용하면 되는데 버블링의 경우에는 클릭한 타깃의 이벤트만 발생하고 상위 요소로 이벤트가 전파되는 것을 막을 수 있다.

버블링에서 작성된 코드에 event.stopPropagation() 을 추가하고 실행해보자.

const clickEvent = (e) => {
  e.stopPropagation();
  console.log(e.currentTarget.className);
};

아까는 DIV3을 클릭했을 때 이벤트가 전파되어 DIV3, DIV2, DIV1 이 출력이 됐지만 이번에는 클릭한 타깃의 이벤트만 발생하는 것을 알 수 있다.

 

4. 이벤트 위임 - Event Delegation

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

<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');
	});
});

자바스크립트 querySelectorAll()를 이용해 화면에 존재하는 모든 인풋 박스 요소를 가져온 다음 각 인풋 박스의 요소에 클릭 이벤트 리스너를 추가한다.

화면을 실행시키고 각 리스트 아이템의 인풋 박스를 클릭하면 'clicked' alert가 표시된다.

그런데 여기서 리스트 아이템을 추가한다면?

// 새 리스트 아이템을 추가하는 코드
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);

새로 추가된 리스트 아이템에는 클릭 이벤트 리스너가 동작하지 않는다.

코드를 다시 살펴보면, 인풋 박스에 클릭 이벤트 리스너를 추가하는 시점에서 리스트 아이템은 두 개이다. 따라서, 새롭게 추가된 리스트 아이템에는 클릭 이벤트 리스너가 등록되지 않았다.

이런 식으로 매번 새롭게 추가된 리스트 아이템까지 클릭 이벤트 리스너를 일일이 달아줘야 할까?
리스트 아이템이 많아지면 많아질수록 이벤트 리스너를 다는 작업 자체가 매우 번거롭다.

이 번거로운 작업을 해결할 수 있는 방법이 바로 이벤트 위임(Event Delegation)이다.

var itemList = document.querySelector('.itemList');
itemList.addEventListener('click', function(event) {
	alert('clicked');
});

화면의 모든 인풋 박스에 일일이 이벤트 리스너를 추가하는 대신 이제는 인풋 박스의 상위 요소인 ul 태그, .itemList에 이벤트 리스너를 달아놓고 하위에서 발생한 클릭 이벤트를 감지한다.
(이 부분이 앞에서 배웠던 이벤트 버블링이다.)

이렇게 하게 된다면, 리스트 아이템을 새로 추가할 때마다 클릭 이벤트를 달지 않아도 된다! (신기)

위 코드는 현재 인풋 박스의 이벤트만 다루는 것이 아닌 label 태그의 이벤트도 감지한다. event 객체를 이용해 인풋 박스의 이벤트만 감지할 수 있도록 구현해보자!

https://velog.io/@tlatjdgh3778/%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%B2%84%EB%B8%94%EB%A7%81%EA%B3%BC-%EC%BA%A1%EC%B2%98%EB%A7%81%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A0%95%EB%A6%AC

 

이벤트 버블링과 캡처링에 대한 정리

이벤트 버블링과 이벤트 캡처링에 대해서 알아보자.이벤트 버블링이란 한 요소에 이벤트가 발생하면 이 요소에 할당된 핸들러가 동작하고, 이어서 부모 요소의 핸들러가 동작하고 최상단의 부

velog.io

 

728x90
반응형

'기술면접 준비' 카테고리의 다른 글

자바 스프링 면접 질문  (0) 2023.01.19
1. javascript 질문과 답안 (5)  (0) 2023.01.19
1. javascript 질문과 답안 (3)  (0) 2023.01.15
1. javascript 질문과 답안 (2)  (0) 2023.01.11
1. javascript 질문과 답안 (1)  (2) 2023.01.10