💫 이벤트 버블링(Event Bubbling)
- 어떤 요소에 대한 이벤트가 발생했을 때, 해당 요소의 최상위 부모까지 이벤트가 전달되어지는 과정
자식노드에서 부모노드 순으로 이벤트를 실행
JavaScript는 기본적으로 이벤트 버블링을 기반으로 동작한다.
★★★
🌞 BOM Event > 이벤트 버블링
<div id="p1" class="box">
<div id="p2" class="box">
<div id="p3" class="box"></div>
</div>
</div>
<script>
const box1 = document.getElementById('p1');
const box2 = document.getElementById('p2');
const box3 = document.getElementById('p3');
p1.onclick = function(event) {
alert('빨강');
};
p2.onclick = function(event) {
alert('노랑');
};
p3.onclick = function(event) {
alert('파랑');
};
</script>
💫 이벤트 캡처링(Event Capturing) = 이벤트 터널링(Event Tunneling)
- 어떤 요소에 대한 이벤트가 발생했을 때 최상위 부모로부터 이벤트가 발생된 요소까지 이벤트가 전달되어지는 과정
부모노드에서 자식노드 순으로 이벤트를 실행
이벤트 캡처링 방법
- 세번째 인자
true
: 이벤트 캡처링 할거야
- false / 아예 쓰지 않음 : 이벤트 버블링 할거야
target.addEventListener('이벤트', 콜백 함수, {capture:ture});;
🌞 DOM Event > 이벤트 버블링 or 이벤트 캡처링(이벤트 터널링)
[예제] 이벤트 캡처링
<div id="p1" class="box">
<div id="p2" class="box">
<div id="p3" class="box"></div>
</div>
</div>
<script>
const box1 = document.getElementById('p1');
const box2 = document.getElementById('p2');
const box3 = document.getElementById('p3');
p1.addEventListener('click', function() {
alert('빨강');
}, true);
p2.addEventListener('click', function() {
alert('노랑');
}, true);
p3.addEventListener('click', function() {
alert('파랑');
}, true);
};
</script>
[예제] 이벤트 버블링
<div id="p1" class="box">
<div id="p2" class="box">
<div id="p3" class="box"></div>
</div>
</div>
<script>
const box1 = document.getElementById('p1');
const box2 = document.getElementById('p2');
const box3 = document.getElementById('p3');
p1.addEventListener('click', function() {
alert('red');
});
p2.addEventListener('click', function() {
alert('yellow');
},false);
p3.addEventListener('click', function() {
alert('blue');
});
</script>
[예제] Hover Table 1
<h1>테이블</h1>
<table class="table">
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
<tr>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
<td>item</td>
</tr>
</table>
- <tr> -> 이벤트 매핑
- 행 단위로 색상 바꾸기
const table = document.getElementsByClassName('table')[0];
const row = table.firstElementChild.children;
for (let i=0; i<row.length; i++) {
row[i].onmouseover = function(event) {
event.target.parentElement.bgColor = 'gold';
event.currentTarget.bgColor = 'gold';
};
row[i].onmouseout = function(event) {
event.currentTarget.bgColor = 'transparent';
};
};
- 테이블에서는 영역이 겹치기 때문에 무조건 event.srcElement는 td에 걸리게 된다.
- 영역이 겹쳐있는 상태에서 자식이 존재하면 이벤트는 자식까지 왔다가 유턴을 한다.
[예제] Hover Table 2
<h1>테이블</h1>
<table class="table" id="tbl2">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<script>
const tbl2 = document.getElementById('tbl2');
const trlist = tbl2.firstElementChild.children;
for (let i=0; i<trlist.length; i++) {
const tdlist = trlist[i].children;
for (let j=0; j<tdlist.length; j++) {
tdlist[j].addEventListener('mousedown', function(event) {
if (event.buttons == 1) {
if (event.target.nodeName == 'TD') {
let img = document.createElement('img');
img.setAttribute('src', 'images/rect_icon01.png');
event.target.appendChild(img);
} else {
let td = event.target.parentElement;
td.removeChild(event.target);
let img = document.createElement('img');
img.setAttribute('src', 'images/rect_icon01.png');
td.appendChild(img);
}
} else if (event.buttons == 2) {
if (event.target.nodeName == 'TD') {
let img = document.createElement('img');
img.setAttribute('src', 'images/rect_icon02.png');
event.target.appendChild(img);
} else {
let td = event.target.parentElement;
td.removeChild(event.target);
let img = document.createElement('img');
img.setAttribute('src', 'images/rect_icon02.png');
td.appendChild(img);
}
} else if (event.buttons == 4) {
event.target.parentElement.removeChild(event.target);
}
});
}
}
window.oncontextmenu = function() {
return false;
};
</script>