오늘의 명언
“ 당신은 소프트웨어 품질을 추구할 수도 있고, 포인터 연산을 할 수도 있다. 그러나 두 개를 동시에 할 수는 없다. ”
-
베르트랑 마이어 (Bertrand Meyer)
300x250
이벤트 전파 (Event Propagation)
이벤트 전파(Event Propagation) 란. HTML 요소에서 이벤트가 발생했을 때 연쇄적인 흐름이 일어나게 되는데
이러한 현상을 이벤트 전파(Event Propagation) 라고 하며, 전파 방향에 따라서 버블링과 캡쳐링으로 구분 짓는다.
이벤트 버블링(Bubbling)
- HTML 요소에서 이벤트가 발생하면 이 요소에 할당된 핸들러가 동작하고, 이어서 바깥 부모 요소의 핸들러가 작동되며 끝으로 최상단 부모 요소까지 반복되어 핸들러가 작동된다. 즉 자식 요소에서 발생한 이벤트 핸들러가 최상단 부모요소까지 전파되는 것이다.
<style>
body * {
margin: 10px;
border: 1px solid blue;
}
</style>
<form onclick="alert('form')">FORM
<div onclick="alert('div')">DIV
<p onclick="alert('p')">P</p>
</div>
</form>
- 가장 안쪽 p 태그를 클릭하면 버블링 원리로 p 태그부터 최상단까지 onclick 이벤트 핸들러가 동작합니다.
대부분 이벤트는 버블링 됩니다. 물론 몇몇 이벤트를 제외하고는 전부 이벤트는 버블링이 된다고 알고 계시면 됩니다.
이벤트 버블링(Bubbling) 중단
- 이벤트를 완전하게 처리한 후 버블링을 중단하도록 명령할 수 있습니다.
- 이벤트 객체의 메서드인 event.stopPropagation()를 사용하면 됩니다.
<body onclick="alert(`이벤트가 실행하지 않습니다.`)">
<button onclick="event.stopPropagation()">클릭해 주세요.</button>
</body>
- Button "클릭해 주세요"를 클릭하여도 body에 alert() 이벤트는 동작하지 않습니다,
이벤트 캡쳐링(Capturing)
- 버블링과는 반대로 자식에서 발생한 이벤트 핸들러가 최 상단 부모에서 시작해 제일 아래 자식 요소까지 전파되는 것을 말한다.
캡쳐링에 경우 이용하는 것이 흔지않기때문에 간혹 실무에서 유용한 경우가 있어서 설명해 봅니다.
타깃 단계에서 트리거 되며 addEventListener() 함수의 3번째 매개변수로 True, false 값으로 사용합니다.
// 캡쳐링
const form = document.querySelector("#form")
form.addEventListener('click', (e) => { ... }, true);
form.addEventListener('click', (e) => { ... }, {capture: true});
// 캡쳐링 핸들러 지울때
// 위에 처럼 캡쳐링 이벤트를 할당해줬으면, 핸들러를 지울땐 같은 단계에 있어야 지워집니다.
form.removeEventListener('click', (e) => { ... }, {capture: true});
<form>FORM
<div>DIV
<p>P</p>
</div>
</form>
<script>
for(let elem of document.querySelectorAll('*')) {
elem.addEventListener("click", e => alert(`캡쳐링: ${elem.tagName}`), true);
elem.addEventListener("click", e => alert(`버블링: ${elem.tagName}`));
}
</script>
이 예시는 어떤 핸들러가 동작하는지 과정을 보여줍니다.
- p 태그를 클릭하면 다음과 같이 동작합니다.
- HTML(최상단) -> BODY -> FORM -> DIV (캡쳐링 동작)
- P (타깃, 캡쳐링과 버블링 두 개의 이벤트가 호출)
- DIV -> FORM -> BODY -> HTML (버블링 동작)
이렇게 캡쳐링 설정을 하고 타깃을 선택하여 이벤트를 실행하면 제일 먼저 캡쳐링 단계부터 타깃 단계, 버블링 단계
이런 순서로 이벤트가 동작하게 됩니다. 캡쳐링은 잘 사용되지 않으니 동작과정만 보시면 될 거 같습니다.
참고
반응형
잘못된 내용이 있으면 댓글 부탁드립니다. 감사합니다.