웹페이지를 해석해서 보여주는 브라우저(Browser)의 동작방식 중에는 '이벤트 버블링(Event Bubbling)'이라는 현상이 존재합니다. 왠지 용어가 일반적이지 않고 뭔가 전문가 포스 같은 느낌이 나서 괜히 어렵게 느껴지는 것도 같습니다. 일반적인 사용 케이스에서 살펴보자면, 버튼을 누른 것도 아니고 배경화면을 클릭한 것 뿐인데도 모달창이 닫히게 되는, 뭐 그런 현상들이 바로 이벤트 버블링 현상이 만들어내는 경우입니다.
이번 포스팅에서는 이러한 '이벤트 버블링'과 관련하여 "전문적"이 아닌 "현상적"인 이해를 경험 해보기로 합니다.
이벤트 버블링(Event Bubbling)
일단 테스트를 위한 코드를 간단하게 작성해보도록 합니다.
div 태그로 박스를 세 개 만들었습니다.
<div class="outer">
<div class="middle">
<div class="inner">이벤트 버블링</div>
</div>
</div>
<style>
.inner {
background: yellow;
width: 200px;
height: 100px;
}
.middle {
background: green;
width: 300px;
height: 200px;
}
.outer {
background: dodgerblue;
width: 400px;
height: 300px;
}
</style>
아래 이미지와 같은 서로 다른 색상의 박스 3개가 겹쳐서 생성되었습니다.
Javascript를 다음과 같이 추가로 작성해보았습니다.
<script>
document.querySelector(".outer").addEventListener("click", function () {
console.log("눌림");
document.body.style.backgroundColor = "black";
});
</script>
가장 바깥을 감싸고 있는 div 박스에 '이벤트 리스너'를 달아주고, 클릭을 감지하도록 했습니다. 클릭이 일어나면 콘솔창에 "눌림"이라 찍어주고 배경화면을 black으로 변경해주는 코드입니다.
어디 한번 클릭해봅시다.
콘솔에 '눌림'이라 찍어주고 배경도 검정색으로 잘 변경됩니다. 그런데 outer 박스 이외로, 중간에 위치한 middle 박스나 가장 안쪽의 inner 박스도 한번 클릭해보세요. 모두 다 검정색으로 배경이 변하게 됩니다. 어라? 뭔가 약간 희한하지 않은가요?
이벤트와 이벤트 리스너
이벤트는 브라우저 상에서 발생하는 어떠한 사건(event)을 말합니다. 클릭하거나 스크롤 하거나, 창이 줄어들어가, 사용자가 뭔가를 입력하거나, 화면이 새로고침 되거나 하는 온갖 사건현상들을 말합니다. addEventListener() 함수는 그러한 이벤트를 감지해주는 기능을 합니다.
이벤트 리스너가 감지된 후 실행하는 함수에 인자로 e를 넣어주면(관례적으로 event의 e를 넣음), 이벤트 객체가 생성되어 다양한 컨트롤이 가능해지게 됩니다.
e.target
이벤트 객체(e)에서 target 속성은 이벤트가 발생한 타겟을 가리킵니다. 위 예제의 경우에는 '클릭'을 한 대상이 되는 것이죠. 코드를 조금 수정하여 outer, middle, inner 박스를 각각 클릭해보면 e.target이 어떻게 변하는 지 확인해보도록 합니다.
document.querySelector(".outer").addEventListener("click", function (e) {
console.log("눌림");
console.log(e.target);
document.body.style.backgroundColor = "black";
});
가장 큰 상자부터 차례로 클릭해보면, 아래와 같이 콘솔에 클릭한 대상을 정확하게 찍어 줍니다.
e.target은 매우 자주 등장하는 이벤트 속성이므로 이참에 뽝!!! 이해를 해두도록 합니다.
e.currentTarget
그럼 비슷하게 생긴 e.currentTarget은 어떤 것을 타겟으로 잡아줄까요?
쉽게 이해하자면, addEventListener가 붙어 있는 당사자를 잡아줍니다. 코드를 살짝 수정하고 다시 한번 박스들을 차례로 클릭해봅니다.
console.log(e.currentTarget);
콘솔에 찍힌 결과를 보면, 3개의 박스를 클릭해보았지만, 가장 바깥의 박스만을 리턴해주고 있습니다. 왜냐하면 addEventListener가 outer 박스에만 붙어 있기 때문에 그렇습니다.
e.target과 e.currentTarget은 비스무리하게 생겨서 헷갈리기 쉬운데요, 일단은 요 정도로 기억을 해두고 추후 <이벤트 위임>이라는 기능을 정리하게 될 때 다시 다뤄보도록 하겠습니다.
e.currentTarget == this
한편 이번 예제의 경우, e.currentTarget은 this라는 키워드로 대체해서 사용할 수 있습니다. 고수들의 자바스크립트 코드에서 자주 만나게 되는 this를 우리는 여기서 처음 만나보게 되는 것 같습니다.^^; 이 참에 아주 조금 this를 맛보고 넘어가도록 해봅시다. 이렇게 한번 비교를 해보면 좋을 것 같습니다.
console.log(e.currentTarget);
console.log(this);
e.currentTarget과 this 둘 다 동일한 div 박스를 선택해주고 있습니다.
작은 박스(inner)만 클릭되게 만들기
안쪽의 가장 작은 박스를 클릭했을 경우에만 동작하도록 하려면 어떻게 코드를 작성하면 좋을까요?
outer, middle을 클릭했을 때는 동작하지 않고, inner를 클릭했을 때만 동작한다.
→ 뭔가 If 조건문을 사용할 것만 같은 느낌적인 느낌이 드는 것도 같습니다.
Javascript 코드를 다음과 같이 작성해봅니다.
<script>
document.querySelector(".outer").addEventListener("click", function (e) {
console.log("눌림");
console.log(e.target);
if (e.target == document.querySelector(".inner")) {
document.body.style.backgroundColor = "black";
}
});
</script>
outer 박스와 middle 박스를 클릭해보았지만, 배경색상은 바뀌지 않습니다. If 조건문 때문이겠죠?
그리고, inner 박스를 클릭해보면, 배경색상이 검정색으로 잘 바뀌는 것을 확인할 수 있습니다.
마치며
브라우저에서 발생하는 이벤트와 그 이벤트를 핸들링 하는 방법은 매우 다양합니다.(사실 저도 다는 모릅니다)
이벤트를 다루다보면 반드시 등장하는 게 e.target과 e.currentTarget입니다.
때문에 너무 깊고 복잡하게 들어가기 전에 일단 이 두 가지 속성에 대해 명확하게 이해를 해두면 좋을 것입니다. 뭔가 복잡한 내용 같지만, 조금씩 파악하고 이해하다보면 언젠가는 자유자재로 이벤트를 핸들링하는 날이 올 것입니다.
즐거운 코딩생활, 즐코딩.
KINcoding
'Javascript' 카테고리의 다른 글
[Javascript] 반복문 for.. in 과 for.. of 의 차이 (2) | 2023.01.05 |
---|---|
forEach, for...in을 이용한 반복문 기초(ft. 배열, 객체 Data 뽑기) (0) | 2023.01.04 |
Alert창 버튼 클릭으로 띄우기(ft. modal, 모달, 팝업) (0) | 2022.12.31 |
Javascript의 변수 선언: var, let, const는 서로 어떻게 다를까? (0) | 2022.12.30 |
getElementById를 쓸까, querySelector를 쓸까? (0) | 2022.12.27 |
댓글