이벤트 객체와 bubbling을 이용해 동적으로 생긴 자식도 처리합니다.
이벤트의 target은 실제 시작 요소이고 currentTarget은 현재 리스너가 등록된 요소입니다. 많은 이벤트가 조상으로 bubbling되므로 부모 하나에서 target.closest로 원하는 자식을 찾는 이벤트 위임을 사용할 수 있습니다. removeEventListener를 쓰려면 등록한 함수 참조를 보관합니다.
리스너는 버튼 두 개가 아니라 그 부모 div 하나에만 등록됩니다. HTML 버튼을 누르면 클릭이 div까지 버블링되고, event.target.closest가 data-course 속성을 가진 button을 찾아 dataset.course 값으로 HTML 선택을 출력합니다. 다만 그 출력이 pre의 textContent를 바꾸면서 목록까지 지우므로, 다른 버튼을 고르려면 코드 실행을 다시 눌러야 합니다.
모든 이벤트가 버블링되지는 않습니다. focus와 blur, mouseenter와 mouseleave는 부모로 올라가지 않기 때문에, 입력칸 포커스를 위임으로 처리하려면 버블링되는 focusin과 focusout을 등록하고 마우스 진입은 mouseover와 mouseout으로 대신합니다.
stopPropagation을 습관적으로 사용하면 상위 컴포넌트의 위임과 분석 이벤트를 예상치 못하게 막을 수 있습니다.
직접 바꿔보세요JavaScript 버튼을 동적으로 추가하고 부모 리스너가 그대로 동작하는지 확인하세요.