안녕하세요, 오늘은 이벤트 버블링, 이벤트 캡처, 그리고 이벤트 위임에 대해서 알아보겠습니다!
이번 cookieparking 프로젝트를 진행하면서 이벤트 핸들링 할 경우가 많았었는데, 그 과정에서 stopPropagation
이나 preventDefault
등을 사용하게 된 이유를 아래의 개념을 살펴보며 알 수 있었습니다.
(사실, preventDefault()를 사용하지 않기 위해 button
태그보단 div
태그에 이벤트 리스너를 달아서 버튼처럼 작동하도록 구현한 경우가 많았습니다.)
이벤트(event)
사건
을 의미합니다.event listener(event handler)
addEventListenr()
를 통해 이벤트를 감지할 수 있습니다.const onClickBtn = () => {
console.log('버튼 클릭!');
}
<button onClick={onClickBtn}>버튼<button/>
이벤트 버블링은 특정 화면 요소에서 이벤트가 발생했을 때 해당 이벤트가 더 상위의 화면 요소들 즉 부모 요소들로 전달되어 가는 특성을 의미합니다.
이번에 진행한 CookieParking 프로젝트에서 Card 요소에 onClick
이벤트로 해당 링크로 연결하도록 구현했고, 하위 요소(자식 요소) hover시에 삭제버튼과 공유버튼을 만들어서 onClick
시 복사와 삭제가 되도록 구현했습니다.
삭제와 공유버튼을 클릭하면, 부모요소에도 onClick 이벤트가 걸려있으므로 클릭 시 이벤트 버블링에 의해 삭제와 링크 연결 두 가지 기능이 동작하게 됩니다.
즉 각 부모 자식 관계를 가진 태그들이 event
를 가지고 있다면, 자식 요소에서 이벤트가 발생한 경우 부모 요소로 이벤트가 전파 되는 현상을 이벤트 버블링
이라고 합니다.
stopPropagation()
이를 해결하기 위해서 e.stopPropagation()
를 사용했습니다.
해당 자식 요소에서만 이벤트를 발생시키고 부모 요소로까지 버블링 되는 것을 막아주는 역할을 합니다.
addEventListener()
부분에 옵션으로 capture: true
를 주어 설정할 수 있습니다.var inputs = document.querySelectorAll('input');
inputs.forEach(function(input) {
input.addEventListener('click', function(event) {
alert('clicked');
});
});
다음과 같이 자식 요소들에게 이벤트 리스너를 달아준 모습입니다.
하지만 이 상태에서 다음과 같이 새로운 list 요소를 만들어 주면, 또 이벤트 리스너를 각각 달아줘야 하는 문제가 있습니다.
var itemList = document.querySelector('.itemList');
var li = document.createElement('li');
var input = document.createElement('input');
var label = document.createElement('label');
input.setAttribute('type', 'checkbox');
input.setAttribute('id', 'item3');
li.appendChild(input);
itemList.appendChild(li);
이를 해결하기 위해
var itemList = document.querySelector('.itemList');
itemList.addEventListener('click', function(event) {
alert('clicked');
});
list의 상위 요소(부모 요소)에 이벤트 리스너를 한 번만 등록해 주면 하위 요소(자식 요소)를 클릭했을 때 이벤트 버블링이 일어나 상위 요소(부모 요소)로 까지 이벤트가 전달됩니다.
좋은 자료 감사합니다!