표준 DOM 이벤트에서 정의한 이벤트 흐름은
위 세 단계로 이뤄집니다!
각 단계를 하나하나 상세하게 보겠습니다.
addEventListenr
의 capture
옵션을 임의로 true로 설정해야됩니다. (디폴트 값인 false는 이벤트 버블링을 잡아내지 못한다.)elem.addEventListener(..., {capture: true})
// 아니면, 아래 같이 {capture: true} 대신, true를 써줘도 됩니다.
elem.addEventListener(..., true)
focus
와 같이 종종 버블링되지 않는 이벤트도 있습니다.<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>
그렇다면, 정확히 어떤 요소에서 이벤트가 발생했는지는 알기 위해서는 어떻게 해야할까요?
event.target
이용하면 됩니다!
- event.target은 실제 이벤트가 시작된 ‘타깃’ 요소입니다. 실제 이벤트가 발생한 요소를 의미합니다. (이벤트 발생 위치)
- event.currentTarget은 이벤트가 부착되어 있는 요소를 의미합니다. (이벤트 생성 위치)
event.stopPropagation()
를 이용해 중단시킬 수 있습니다<body onclick="alert(`버블링은 여기까지 도달하지 못합니다.`)">
<button onclick="event.stopPropagation()">클릭해 주세요.</button>
</body>
onClick
이벤트가 버블링 되지 않고 오로지 button
테그 에서만 실행됩니다.그러나 이벤트 버블링 중단은 거의 사용하지 않고, 사용한 핸들러마저 죽은 이벤트가 되어버리기 때문에 섣불리 사용하면 위험합니다!
아래 코드의 실행 양상을 살펴봄으로써 이벤트 캡처링과 버블링을 이해할 수 있습니다.
<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>
캡처링과 버블링을 활용해 강력한 이벤트 핸들 방식인 이벤트 위임을 사용할 수 있습니다!
이벤트 위임은 하위 요소에 각각 이벤트를 붙이지 않고 상위 요소에서 하위 요소의 이벤트들을 제어하는 방식입니다.
사용방법
<h1>오늘의 할 일</h1>
<ul class="itemList">
<li>
<input type="checkbox" id="item1" />
<label for="item1">솝트 조별과제</label>
</li>
<li>
<input type="checkbox" id="item2" />
<label for="item2">솝트 세미나</label>
</li>
</ul>
let inputs = document.querySelectorAll("input");
inputs.forEach(function (input) {
input.addEventListener("click", function (event) {
alert("clicked");
});
});
ul
에서 이벤트 위임을 이용하면 이벤트핸들러를 전부 할당하지 않고 이벤트를 적용시킬 수 있습니다!let itemList = document.querySelector('.itemList');
itemList.addEventListener('click', function(event) {
alert('clicked');
});
레퍼런스는 쿠키파킹을 통해 확인할 수 있습니다~
https://www.cookieparking.com/share/U2FsdGVkX1_bVF5luMLe55H2Mdt7CkrBrjpTLSxZR7QnpTL3y0jB6NYQ_mOiaTbuUTzzjzWsVqeWiPgy4NvNIsQQ0z7rXjPOGiict_WkZyA
정리 잘되어 있네요ㅎ 잘보고 갑니다~
감사합니다👍👍