Change Logs
- 2022.04.24 - 용어 수정: 자식 -> 자손, 자손 -> 자손 Element. 링크가 정확한 Anchor 에 가도록 수정
<form id="form">
<button type="submit">button</button>
</form>
<script>
form.addEventListener('submit', (event) => {
event.preventDefault();
console.log(event.currentTarget);
})
</script>
자주 써왔던 아주 일반적인 이벤트 핸들러 할당방법입니다. 이벤트가 발생된 Element 를 뽑아오기 위해서는, event.target
을 사용하고 event.currentTarget
또한 사용해왔습니다.
여기서 한가지 의문이 있습니다. e.target
과 event.currentTarget
둘 중, 어느것을 사용해야 하는가? 답은, 일반적으로 event.currentTarget
을 사용해야 한다는 것입니다.
이벤트 객체에 대한 MDN 공식문서를 살펴보면, 다음과 같은 설명이 있습니다.
event.currentTarget
은 이벤트 핸들러가 할당된 Element 를 의미하고, event.target
은 디폴트 이벤트가 맨 처음 발생한 자손 Element(이벤트 핸들러가 Capturing Phase 에 발생하든 Bubbling Phase 에 발생하든 가장 자손 Element 였습니다)을 의미합니다.
결론은, 이벤트 핸들러에서 자신이 의도한 대로 핸들러가 할당된 Element 를 가져오고 싶을 때는 event.currentTarget
을 사용해야 한다는 것입니다.
그렇다면 event.target
은 언제 사용해야 하는지, 그 답은 이벤트위임(Event Delegation) 패턴에 있습니다.
이벤트 위임이란, 조상 Element의 이벤트를 자손 Element에게 위임한다는 뜻입니다. 어떻게 위임하는지 그 Key가 궁금한데요, 바로 앞서 말씀드린 event.target
에 있습니다. event.target
을 사용하면 조상의 이벤트 핸들러에서 맨 처음 이벤트가 발생한 자손 Element를 가져올 수 있습니다. 이러한 연관관계에 의해 이벤트 위임이 가능해지는 구조입니다.
<div id="menu">
<button data-action="save">저장하기</button>
<button data-action="load">불러오기</button>
<button data-action="search">검색하기</button>
</div>
<script>
// 이해 용도
menu.addEventListener('click', (event) => {
let target = event.target;
if (target.tagName != 'BUTTON') return;
// 여기서 원하는 작업 진행(예를들어 dataset에서 action을 뽑아 구분하여 작업)
});
// 실무 활용법
menu.addEventListener('click', (event) => {
let button = event.target.closest('button');
if (!button) return;
if (!menu.contains(button)) return;
// 여기서 원하는 작업 진행(예를들어 dataset에서 action을 뽑아 구분하여 작업)
});
</script>
menu의 자손 Element 인 버튼을 클릭했을때 event.target
은 버튼 Element 가 됩니다. 따라서 이를 구분하는 로직만 이벤트 핸들러에 넣어주면, 버튼을 감싸고 있는 조상 Element의 이벤트 핸들러 하나만으로도 여러가지 버튼 클릭을 처리할 수 있습니다. 때문에 코드량이 줄어든다는 막강한 장점이 있습니다.
이 정도가 event.target
을 이용한 이벤트 위임(Event Delegation)의 핵심입니다. Javascript DOM API 에 기반하여 다양한 방식으로 값을 꺼네오고 처리하는 것은 이제 우리 개발자의 몫입니다. 클래스를 사용하여 좀더 힙 한 코드를 구성할 수도 있고, 행동 패턴이라는 구체적인 컨셉을 이용하여 좀 더 짧은 코드를 진행할 수도 있습니다.
내가 해야할 마인드셋
1.event.target
에 알맞은 값을 세팅하고 뽑아오기 위해 HTML 에 대한 공부를 게을리 하지말고 DOM API 의 깊은 이해력을 갖추자. (외우진 말고 뭐가 있는지 정도만 아는 폭 넓은 배경지식을 탑재하자)
2. 좀 이벤트 핸들러 할당이 중복되고 많다? 찝찝하다 싶으면 이벤트 위임을 고려해보자.
3. 클래스를 최대한 고려해보도록 노력해보자. 웬만하면 안 쓰는게 나을것 같긴 한데, 만약 컴포넌트 형태라면? 그때는 클래스를 사용한 패턴을 적용하면 정말 많이 도움될것 같다.