일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 이벤트위임
- 전역변수
- INCLUDES
- 프론트엔드
- 비동기적
- 자바스크립트
- 버블링
- git
- text-align
- 지역변수
- 단락회로평가
- 자바스크립트기초
- map()
- 비구조화
- 리액트
- 동기적
- 코딩공부
- 돔조작
- icoMoon
- 중앙정렬
- truthy
- js
- 이벤트리스너
- falsy
- async
- addEventListener
- 캡쳐링
- 논리연산자
- 어웨이트
- Await
- Today
- Total
피리부는 사나이 (pied piper)
[JS] 이벤트 핸들러 3가지와 이벤트 위임 (Event Delegation) 본문
이벤트 핸들러
: 이벤트가 발생했을 때 브라우저에 호출을 위임한 함수.
1. 이벤트 핸들러 어트리뷰트 방식
: HTML 요소의 어트리뷰트 중에 이벤트에 대응하는 핸들러 어트리뷰트 값으로 함수 호출문 등의 statement를 할당하면 핸들러 등록 됨
<button onclick="sayHi('Lee')" > CLick me!</button>
<script>
function sayHI(name) {
console.log(`Hi ${name}.`);
};
</script>
하지만 HTML과 JS는 관심사가 다르므로 혼재하는 것보다 분리하는 것이 좋음.
그러므로 이 1번 방식은 사용하지 않는 것이 더 좋음
2.이벤트 핸들러 프로퍼티 방식
: window 객체와 Document, HTMLElement 타입의 DOM 노드 객체는 이벤트에 대응하는 핸들러 프로퍼티를 가지고 있음. 프로퍼티에 함수를 바인딩하면 이벤트 핸들러 등록 됨
const $button = document.querySelector('button');
$button.onclick = function () {
console.log('button click');
};
핸들러를 등록하기 위해서는 이벤트를 발생시킬 객체인 event target과 이벤트의 종류를 나타내는 문자열인
event type, 이벤트 핸드러를 지정해야 함.
3. addEventListener 메서드 방식
: DOM 레벨 2에서 도입된 EventTarget.prototype.addEventListener 메서드를 사용해서
이벤트 핸들러를 등록 가능. 1번과 2번은 레벨 0부터 제공된 방식
이 메서드의 장점은 기존 프로퍼티 방식은 하나 이상의 이벤 핸드러를 등록할 수 없지만 하나 이상의 이벤 핸들러를 등록 가능 (등록된 순서대로 호출)
이벤트 핸들러 제거 :
addEventListener로 등록한 이벤트 핸드러를 제거하려면 removeEventListener를 사용하면 된다.
이 메서드에 전달할 인수는 addEventListener와 동일하다.
(일치 하지 않으면 이벤트 핸들러 제거 X)
이벤트 전파
:DOM 트리 상에 존재하는 DOM 요소 노드에서 발생한 이벤트는 DOM 트리를 통해 전파.
<예시>
<ul id="fruits">
<li id="apple">Apple</li>
<li id="banana">Banana</li>
<li id="orange">Orange</li>
</ul>
ul 요소의 두 번째 자식 요소인 li요소를 클릭하면 클릭 이벤트 발생.
이때 생성된 이벤트 객체는 이벤트를 발생시킨 DOM 요소인 eventTarget을 중심으로 DOM트리를 통해 전파.
이벤트 객체가 전파되는 영향에 따라
3단계로 구분
- 캡쳐링 단계 : 이벤트가 상위 요소에서 하위 요소 방향으로 전파
- 타깃 단계 : 이벤트가 이벤트 타깃에 도달
- 버블링 단계 : 이벤트가 하위요소에서 상위 요소 방향으로 전파
예를 들어, ul요소에 이벤트 핸들러를 바인당하고 하위 요소인 li 요소를 클릭하여 이벤트 발생 시킨다면,
이때 event.target은 ‘li’요소이고 eventcurrentTarget은 ul 요소가 됨
<예제>
<ul id="fruits"> //current.Target
<li id="apple">Apple</li>
<li id="banana">Banana</li> //event.Target
<li id="orange">Orange</li>
</ul>
$fruits.addEventListener('click', e => {
console.log(`이벤트 단계 : ${e.eventPhase}` ); // 3: 버블링
console.log(`이벤트 타깃 : ${e.target}` ); // [object HTMLElement]
console.log(`이벤트 타깃 : ${e.currentTarget}`); // [object HTMLEUlistElement]
- 'li’ 요소를 클릭하면 클릭 이벤트가 발생하여 클릭 이벤트 객체 생성 => li 요소가 eventTarget 됨
- 클릭 이벤트 객체는 window에서 시작해서 eventTarget 방향으로 전파 (캡처링 단계)
- 이벤트 객체는 이벤트를 발생시킨 eventTarget에 도달 (타깃 단계)
- 이벤트 객체는 이벤트 객체에서 시작해서 window 방향으로 전파 (버블링 단계)
이벤트 위임 (Event Delegation)
: 여러 개의 하위 DOM 요소에 각각 이벤트 핸들러를 등록하는 대신 하나의 상위 DOM 요소에 이벤트 핸들러를
등록하는 방법
이것을 이용하면 상위 DOM요소에 이벤트 핸들러 등록으로 여러 개의 하위 DOM 요소에 이벤트 핸들러를 여러 개 따로 등록할 필요가 없음.
<예제>
<ul id="fruits"> //current.Target
<li id="apple">Apple</li>
<li id="banana">Banana</li> //event.Target
<li id="orange">Orange</li>
</ul>
<div> <em class="msg">apple</em></div> // 선택된 내비게이션 아이템
<script>
const fruits = document.getElementById('fruits');
const msg = document.getElementById('msg');
function activate ({target}) {
if(!target.matches(#fruits > li)) return;
[...$fruit.classList.toggle('active', $fruit === target);
$msg.textContent = target.id;
});
}
$fruits.onclick = activate;
</script>
이벤트 위임을 통해 하위 DOM 요소에 발생한 이벤트 처리 할 때 주의점은 상위 요소에 이벤트 핸들러를 등록하기 때문에
이벤트 타깃, 즉 이벤트를 실제로 발생시킨 DOM 요소가 개발자가 기대한 DOM 요소가 아닐 수 있음.
따라서 이벤트에 반응이 필요한 DOM 요소에 한정하여 실행되도록 eventTarget을 검사해야 함
*Element.prototype.matches 메서드 : 인수로 전달된 선택자에 의해 특정 노드 탐색 가능한지 확인
function activate ({target}) {
if (!target.matches('#fruits > li')) return;
...
//이벤트를 발생시킨 요소(타깃)이 ul#fruits의 자식요소 아니면 무시
일반적으로 이벤트 객체의 target 프로퍼티와 currentTarget 프로퍼티는 동일한 DOM 요소를 가리키지만
이벤트 위임을 통해 상위 DOM 요소에 이벤트 바인딩 한 경우
이벤트 객체의 target 프로퍼티와 currentTarget 프로퍼티가 다른 DOM 요소 가리킬 수 있음
위의 예제는 $fruits요소에 이벤트 바인딩 함.
<예제>
$fruits.onclick = activate;
이떄 이벤트 객체의 currentTarget 프로퍼티는 변함없이 $fruits 요소 가리키지만,
이벤트 객체의 target 프로퍼티는 실제로 이벤트를 발생시킨 DOM 요소를 가리킴.
$fruits 요소도 클릭 이벤트를 발생시킬 수 있으므로 이 경우 이벤트 객체의 currentTarget 프로퍼티와
target 프로퍼티는 동일한 $fruits를 가리키지만 $fruits 요소의 하위 요소에 클릭 이벤트가 발생한 경우
이벤트 객체의 currentTarget 프로퍼티와 target 프로퍼티는 다른 DOM 요소를 가리킴
'Java Script' 카테고리의 다른 글
[JS] 대표 비동기 3가지 [콜백, 프라미스, async/await] (0) | 2022.05.02 |
---|---|
[JS] 비 구조화 할당 / Spread 연산 (0) | 2022.04.28 |
[JS] 조건문 업그레이드 (연산자) / 단락회로 평가 (0) | 2022.04.27 |
[JS] 배열 내장 함수들 정리 [map, includes, indexOf 등] (0) | 2022.04.26 |
[JS] 객체 리터럴 (0) | 2022.04.23 |