addEventListener()
API를 이용해서 이벤트 등록을 할 수 있다.
const divs = document.querySelectorAll("div");
divs.forEach((div) => {
div.addEventListener("click", () => {
console.log("hi");
});
});
addEventListener()
는 화면에 동적인 기능을 추가하기 위해서 사용되는 기능이다.
removeEventListener()
API를 이용해서 이벤트 제거를 할 수 있다.
Event Bubbling
)상위의 화면 요소란 한 단계 위에 있는 요소이고
HTML
요소는 기본적으로 트리 구조를 가지고 있다.
<div class="three">
<div class="two">
<div class="one">눌러보세요!</div>
</div>
</div>
const logEvent = (event) => {
console.log(event.currentTarget.className);
};
const divs = document.querySelectorAll("div");
// Event Bubbling
divs.forEach((div) => {
div.addEventListener("click", logEvent);
});
querySelectorAll
을 썼기 때문에 각 태그마다 이벤트가 등록되어 있다.
그래서눌러보세요!
를 클릭하면one
->two
->three
순으로console
에 찍히는 것을 볼 수 있다.
만약 이벤트가 특정div
태그에만 달려 있다면 위와 같은 동작 결과는 확인할 수 없다.
하위 요소에서 상위 요소로 이벤트가 전파되는 방식을 이벤트 버블링 (
Event Bubbling
)이라고 한다.
Event Capture
)body
태그부터 클릭 이벤트가 발생한 지점으로 찾아가는 그림이 나타난다.divs.forEach((div) => {
div.addEventListener("click", logEvent, {
capture: true,
});
});
addEventListener()
API에서 옵션 객체에capture: true
를 설정해주면 된다.
눌러보세요!
를 클릭하면three
->two
->one
순으로console
에 찍히는 것을 볼 수 있다.
event.stopPropagation()
const logEvent = (event) => {
event.stopPropagation();
console.log(event.currentTarget.className);
};
event.stopPropagation()
을 입력하게 되면 이벤트 버블링에서는one
만 찍히게 되고 이벤트 캡쳐에서는three
만 찍히게 된다.
이벤트 버블링이나 이벤트 캡쳐처럼 이벤트 흐름을 제대로 알지 못하면, 예상하지 못한 에러가 발생할 수 있는데,event.stopPropagation()
을 입력하게 되면 에러를 방지할 수 있다.
Event Delegation
)TodoList에서 클릭 이벤트로 새로운 일정(태그)을 만들었다고 했을 때, 해당 일정(태그)에도 이벤트를 줘야 한다.(삭제, 수정 등의 이벤트가 태그에 자동으로 붙는 것이 아니다.)
추가된 일정(태그)에 이벤트를 주려면 이벤트 리스너를 새로 달아야 한다.
처음addEventListener()
에 등록되지 않은 이벤트이기 때문이다.
이러한 작업은 매우 번거롭다.
번거로운 작업을 해결할 수 있는 방법이 이벤트 위임 (
Event Delegation
)이다.
var itemList = document.querySelector(".itemList");
itemList.addEventListener("click", function (event) {
const input = event.target.closest("input");
if (!input) return;
alert("clicked");
});
클릭 했을 때
alert
를 주는 이벤트이다.
input
태그에 이벤트를 주고 싶을 때input
태그들을 다 감싸고 있는 상위 태그의class
이름(.itemList
)으로 이벤트를 등록했다.
.itemList
요소 안에 있는 모든 요소는click
했을 때alert()
가 실행된다.
<li>
<input type="checkbox" id="item2" />
<label for="item2">이벤트 캡쳐 학습</label>
</li>
const input = event.target.closest("input");
if (!input) return;
label
요소도 이벤트를 같이 받기 때문에input
요소만 이벤트로 받아서 처리할 수 있도록 해준다.
closest()
는 메소드를 통해 자신부터 부모 요소 단위로 출발하여 각 요소가 지정한 선택자에 만족할 때까지 탐색한다.
이 중 가장 가깝게 조건에 만족한 부모 요소가 반환된다. 조건에 만족한 요소가 없으면null
값을 반환한다.