<table>
<tr>
<th colspan="3"><em>A</em></th>
</tr>
<tr>
<td class="a1"><strong>A1</strong>
<br>A11<br>A12<br>A13</td>
<td class="a2">...
</td>
<td class="a3">...</td>
</tr>
<tr>...2 more lines of this kind...</tr>
<tr>...2 more lines of this kind...</tr>
</table>
<td>
를 클릭했을 때, 그 칸을 강조하려면: 각<td>
마다 onClick
핸들러를 할당하는 대신, 모든 이벤트를 잡아내는 핸들러를 <table>
요소에 할당 (event.taget
으로 어떤 요소가 클릭되었는지 감지하고 해당 칸을 강조하는 방식)
let selectedTd;
table.onclick = function(event) {
let target = event.target; // 클릭이 어디서 발생한지 저장
if (target.tagName != 'TD') return; // TD에서 발생한 게 아니라면 아무 작업도 하지 않음
highlight(target); // 강조
};
function highlight(td) {
if (selectedTd) { // 이미 강조되어있는 칸이 있다면 원상태로
selectedTd.classList.remove('highlight');
}
selectedTd = td;
selectedTd.classList.add('highlight'); // 새로운 td를 강조
}
table.onClick
핸들러에서 event.target
을 이용해 클릭 이벤트가 <td>
안쪽에서 일어났는지도 구분하려면
table.onclick = function(event) {
let td = event.target.closest('td'); // 가장 가까운 조상의 <td>요소 검색
if (!td) return; // event.target이 <td> 안에 있지 않으면 종료
if (!table.contains(td)) return; // 중첩 테이블이 있는 경우, 현재 테이블 내에 있지 않으면 종료
highlight(td);
};
버튼이 있는 메뉴를 구현할 때, 각 버튼의 기능과 관련된 메서드가 있는 객체를 이미 구현했다면, (버튼 각각에 독립된 핸들러를 할당하는 방식이 아닌) 메뉴 전체에 핸들러를 하나 추가해주고 각 버튼의 data-action
속성에 호출할 메서드를 할당해주기
<div id="menu">
<button data-action="save">저장하기</button>
<button data-action="load">불러오기</button>
<button data-action="search">검색하기</button>
</div>
<script>
class Menu {
constructor(elem) {
this._elem = elem;
elem.onclick = this.onClick.bind(this); // this에 바인딩 해 Menu 객체를 참조
}
save() {
alert('저장하기');
}
load() {
alert('불러오기');
}
search() {
alert('검색하기');
}
onClick(event) {
let action = event.target.dataset.action;
if (action) {
this[action]();
}
};
}
new Menu(menu);
</script>
-> 버튼마다 핸들러를 할당해주는 코드를 작성할 필요가 없고, 메서드를 만들고 HTML에 그 메서드를 써주기만 하면 됨 / 언제든지 버튼을 추가하고 제거할 수 있어 HTML 구조 유연
event.target
사용해 이벤트가 발생한 요소가 어디인지 파악innerHTML
이나 유사 기능 스크립트로 요소 덩어리를 더하거나 뺄 수 있어 DOM 수정 쉬워짐