본문 바로가기

JavaScript/Interactive JavaScript

[JavaScript] 이벤트 위임

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="style.css">
  <title>JS with Codeit</title>
</head>
<body>
  <div id="content">
    <h1 id="title">오늘 할 일</h1>
    <ul id="list">
      <li class="item">자바스크립트 공부</li>
      <li class="item">유튜브 시청</li>
      <li class="item">저녁 약속</li>
      <li class="item">독서</li>
    </ul>
  </div>
  <script src="index.js"></script>
</body>
</html>

 

이벤트를 적용할 때, 아래와 같이 반복문을 사용하여 나타낼 수 있으나,

 

const list = documnet.querySelector('#list');

for(let item of list.children) {
	item.addEventListener('click', function(e) {
    	e.target.classList.toggle('done')
    });
}

const li = document.createElement('li');
li.classList.add('item');
li.textContent = '일기 쓰기';
list.append(li);

'일기쓰기' 를 추가하면 그 추가된 아이템에는 이벤트핸들러가 적용이 되지 않는다.

 

 

 

이벤트 버블링을 활용하면 이를 간단하게 해결할 수 있음.

 

// 이벤트 위임 (Event Delegation)
const list = document.querySelector('#list');

list.addEventListener('click', function(e) {
	e.target.classList.toggle('done');
});

const li = document.createElement('li');
li.classList.add('item');
li.textContent = '일기 쓰기';
list.append(li);

이렇게 부모요소에 이벤트를 하나만 등록을 해주어도 아래의 추가된 아이템이 잘 적용된다.

그러나 부모요소에 등록된 이벤트 핸들러이므로 자식요소를 제외한 온전히 부모 요소를 클릭해도 이벤트가 동작하는 단점이 있음.

 

 

 

// 이벤트 위임 (Event Delegation)
const list = document.querySelector('#list');
list.addEventListener('click', function(e) {
	// if (e.target.tagName === 'LI') // 타겟 프로퍼티의 태그 네임이 li 이거나
	if (e.target.classList.contains('item')) { // 'item' class 를 가지고있는것 중에 추가
		e.target.classList.toggle('done');
	}
});

이처럼 조건을 걸어서 작성하여 해결할 수 있다. 

 

 

 

버블링을 막으려면,

e.stopPropagation(); 메소드를 사용하여 멈출 수 있다.

const li = document.createElement('li');
li.classList.add('item');
li.textContent = '일기 쓰기';
list.append(li);
li.addEventListener('click', function(e) {
  e.stopPropagation();
});

 

그러나 정말 필요한 경우가 아니라면, 이벤트 버블링을 막는 것은 피하는 것이 좋다.