들어가기 전에
list(어떤 목록)가 여러 개인 UI에 각각 비슷한 이벤트를 걸어서 처리해야 한다면 어떻게 해야 할까요?
for문으로 addEventListener를 사용해야 할까요?
학습 목표
- Event delegation을 이해하고, 효율적인 이벤트 등록을 구현할 수 있다.
핵심 개념
- Event delegation
- Bubbling
- Capturing
학습하기
들어가기 전에
list(어떤 목록)가 여러 개인 UI에 각각 비슷한 이벤트를 걸어서 처리해야 한다면 어떻게 해야 할까요?
for문으로 addEventListener를 사용해야 할까요?
학습 목표
핵심 개념
학습하기
우리는 img나 li를 클릭해도 UL에도 이벤트가 발생하고, 이벤트 리스너 실행된다는 것을 알게 됐습니다.
img를 클릭하면 아래 결과는 무엇이 나올까요?
ul 그리고 img 태그가 나옵니다.
ul.addEventListener("click",function(evt) {
console.log(evt.currentTarget.tagName, evt.target.tagName);
});
네 target 정보는 실제 클릭 된 하위 엘리먼트를 알려줍니다!
이 점을 이용해서 src를 추출할 수 있지 않을까요?
이제 addEventListener 메서드를 한 번만 쓰면서 우리는 모든 list의 image 정보를 확인할 수 있습니다.
더구나 list 태그가 하나 더 추가된다고 하여도 문제없이 동작합니다.
var ul = document.querySelector("ul");
ul.addEventListener("click",function(evt) {
if(evt.target.tagName === "IMG") {
log.innerHTML = "clicked" + evt.target.src;
}
});
그런데 작은 문제가 하나 더 있는 거 같네요.
예제를 보면, 이미지 태그는 padding 값이 있어서, img태그와 li 태그 사이에 공백이 존재합니다.
이 부분(공백)을 클릭하면 tagName이 LI라서 위에서 구현한 조건문으로 들어가지 않았기 때문입니다.
이 부분(공백)을 클릭해도 이미지 url을 출력할 수 있으려면 어떻게 해야할까요?
var ul = document.querySelector("ul");
ul.addEventListener("click",function(evt) {
debugger;
if(evt.target.tagName === "IMG") {
log.innerHTML = "clicked" + evt.target.src;
} else if (evt.target.tagName === "LI") {
log.innerHTML = "clicked" + evt.target.firstChild.src;
}
});
전체코드는 여기서 확인 하세요.
생각해보기
참고 자료
https://javascript.info
comment
이거 안보고 todo ajax 버튼클릭 하려니까 매우 힘들었네요
앞에 프론트 강의 별로 없던데 넣어주시지..
혼자서 웹개발을 공부하는데 큰 도움이 되고 있습니다. 무료로 이런 강의를 들을 수 있다니!!
Event Delegation is God Gineung!
실험 결과, bubbling은 target 요소에서 최상위 요소까지 이벤트를 전파하고, Capturing은 최상위 요소에서 target 요소까지 이벤트를 전파합니다. 만약 Capturing에서 li 패딩 영역을 터치하면 target이 li이므로 ul, li 이벤트만 실행됩니다. (img까지 전파되지 않습니다)
https://jsfiddle.net/8ew2bmrh/1/
이벤트 버블링 정리가 너무 잘되어있네요.
https://joshua1988.github.io/web-development/javascript/event-propagation-delegation/
감사합니다~!!
굿.. 명강의 감사합니다.
프젝2에서의 궁금증이 속시원히 해결됐어요
프로젝트 2 할 때 이벤트 하나씩 다 걸어줬었는데 이렇게 하면 되는 것이었군요 ㅠㅠ 감사합니다~~
와 25분 너무 길다고 생각했는데 개꿀이네요.. 이벤트 감사합니다 ㅎ.ㅎ