[JS] Event Delegation 작동방식
안녕하세요, 개발자 Sean입니다.
오늘은 Event Delegation에 대한 좋은 글을 읽어 번역해 옮겨보려고 합니다.
How JavaScript Event Delegation Works
자바스크립트 세계에서 가장 핫한 방법론 중 하나로 event delegation이 있습니다. Event delegation을 사용하면 특정 노드에 이벤트 리스너를 추가하지 않아도 되지요. 대신 부모 엘리먼트에 이벤트 리스터를 추가하면 됩니다. 그렇게 되면 해당 이벤트 리스너는 버블링 된 이벤트를 분석하여 하위 요소에서 일치하는 항목을 찾을 수 있죠. 기본 개념은 매우 간단하지만 많은 사람들이 event delegation이 작동하는 방식을 알지 못합니다. 이번 포스팅에서 event delegation이 작동하는 방식을 설명하고 순수 JavaScript 예제를 설명드리도록 하겠습니다.
부모 ul 엘리먼트 아래 여러 엘리먼트가 있다고 가정을 해보겠습니다:
<ul id="parent-list">
<li id="post-1">Item 1</li>
<li id="post-2">Item 2</li>
<li id="post-3">Item 3</li>
<li id="post-4">Item 4</li>
<li id="post-5">Item 5</li>
<li id="post-6">Item 6</li>
</ul>
또한 각 하위 요소를 클릭할 때 어떤 일이 발생해야 한다고 가정해 보겠습니다. 각각의 개별 li 요소가 목록에서 자주 추가되고 제거되는 경우에는 어떻게 해야할까요? 이벤트 리스너를 추가하고 제거하는 코드가 어플의 다른 곳에 위치한다면 이는 악몽이 될 것입니다. 최선의 방법은 상위 ul 요소에 이벤트 리스너를 추가하는 것입니다. 그러나 이벤트 리스너를 부모 요소에 추가한다면 어떤 요소가 클릭된 것인지 어떻게 알 수 있을까요?
이는 아주 간단합니다. 이벤트가 버블링되어 ul 요소까지 올라오면 이벤트 개체의 대상 속성을 확인해 실제 클린된 노드의 참조값을 얻으면 됩니다. 아래는 event delegation을 설명하는 매우 기본적인 자바스크립트 스니펫입니다.
// Get the element, add a click listener...
document.getElementById("parent-list").addEventListener("click", function(e) {
// e.target is the clicked element!
// If it was a list item
if(e.target && e.target.nodeName == "LI") {
// List item found! Output the ID!
console.log("List item ", e.target.id.replace("post-", ""), " was clicked!");
}
});
우선은 상위 요소에 클릭 이벤트 리스너를 추가합니다. 이벤트 리스너가 트리거 되면 이벤트 요소를 확인하여 반응할 요소 유형인지 확인합니다. 만약 클릭된 요소가 LI 엘리먼트라면 붐! 필요한 값을 찾았습니다! 만약 원하던 엘리먼트가 아니라면 이벤트를 무시하게 됩니다. 이 예제는 아주 간단합니다. ul과 li를 직접적으로 비교할 뿐이죠. 좀 더 어려운 것을 한번 시도해 보겠습니다. 자식 엘리먼트를 많이 가진 부모 div가 있고 그중 classA CSS가 있는 A 태그만 필요한 상황입니다.
// Get the parent DIV, add click listener...
document.getElementById("myDiv").addEventListener("click",function(e) {
// e.target was the clicked element
if (e.target && e.target.matches("a.classA")) {
console.log("Anchor element clicked!");
}
});
Element.matches API를 사용하여, 엘리먼트가 필요로하는 타깃을 충족하는지 확인할 수 있습니다.
대부분의 개발자는 DOM 요소 및 이벤트 처리에 JavaScript 라이브러리를 사용하므로 고급 위임 및 요소 식별이 가능한 라이브러리의 이벤트 위임 방법을 사용하는 것이 좋습니다.
Event delegation의 개념을 시작적으로 이해하고 그 유용성을 이해하는데 도움이 되었길 바랍니다 :)