ul
태그와li
태그를 활용하여 클릭 시 어떤 이벤트가 발생하도록 하는 것은
수많은 프로젝트에서 흔하게 등장하는 기능이다.
그런데, 이런 이벤트들은addEventListener
를 통해 등록을 해줘야한다.
li
는 보통map()
을 통해 나열되는 경우가 많은데, 필자는li
에 일일이 이벤트를 등록해왔다.
하지만, 이제는 이벤트 위임이라는 것을 통해 하나씩 등록할 필요없이 한번에 관리해보려고 한다.
마침 좋은 예시가 있어서 가져와봤다.
게시물을 보여주는 리스트가 있고(정확히는 div
지만), x 버튼으로 게시물을 삭제할 수 있다.
<div id="container">
<div class="pane">
<h3>Horse</h3>
<p>The horse is one of two extant subspecies of Equus ferus. It is an odd-toed ungulate mammal belonging to the taxonomic family Equidae. The horse has evolved over the past 45 to 55 million years from a small multi-toed creature, Eohippus, into the large, single-toed animal of today.</p>
<button class="remove-button">[x]</button>
</div>
<div class="pane">
<h3>Donkey</h3>
<p>The donkey or ass (Equus africanus asinus) is a domesticated member of the horse family, Equidae. The wild ancestor of the donkey is the African wild ass, E. africanus. The donkey has been used as a working animal for at least 5000 years.</p>
<button class="remove-button">[x]</button>
</div>
<div class="pane">
<h3>Cat</h3>
<p>The domestic cat (Latin: Felis catus) is a small, typically furry, carnivorous mammal. They are often called house cats when kept as indoor pets or simply cats when there is no need to distinguish them from other felids and felines. Cats are often valued by humans for companionship and for their ability to hunt vermin.
</p>
<button class="remove-button">[x]</button>
</div>
</div>
만약 삭제 기능을 구현하기 위해서, 모든 게시물의 x 버튼에 이벤트를 등록한다고 해보자.
const btn = document.getElementsByClassName("remove-button");
// 모든 x 버튼에 이벤트를 등록한다.
for (let i = 0; i < btn.length; i++) {
btn[i].addEventListener("click", clickHandler);
}
function clickHandler(event) {
// 클릭된 x 버튼의 부모 요소를 찾고, 해당 요소를 지운다.
event.target.parentNode.remove();
}
이벤트가 발생한 버튼의, 부모 요소를 찾아가서, 그 요소를 삭제하는.
코드가 좀만 길어지면 생각이 꼬여버리는 코드가 작성된다.
또한, 요소 하나하나에 이벤트를 달아줘야하는 귀찮음이 있다.
이는 재렌더링 구현 시, 경우에 따라 모든 요소에 다시 이벤트를 등록하는 문제가 있을 수도 있다.
// 최상위 요소에 이벤트를 등록한다.
container.onclick = function(event) {
// 클릭된 요소의 class가 x 버튼이 아닌 경우 return
if (event.target.className !== 'remove-button') return;
// 클릭된 x 버튼 태그의 가장 근처에 있는 .pane 요소
let pane = event.target.closest('.pane');
// 해당 요소를 지운다.
pane.remove();
};
최상위 요소에만 이벤트를 등록했음에도, 하위 요소에서 발생하는 이벤트를 처리할 수 있다.
이를 통해 훨씬 더 간편하게 이벤트를 다룰 수 있게 된다.
자식 요소가 몇 개가 되든 상관없이 편리하게 이벤트를 등록할 수 있다!
예시에서는 div
를 사용했지만, 저런 구조의 컴포넌트가 있다면 언제든 활용할 수 있다.
단, 모든 이벤트가 위임이 되는 것은 아니니 알아보고 사용하자!!!