40.8 DOM 요소의 기본 동작 조작
40.8.1 DOM 요소의 기본 동작 중단
- DOM 요소는 저마다 기본 동작이 있다.
- ex. a 요소를 클릭하면 href 어트리뷰트에 지정된 링크로 이동
- 이벤트 객체의 preventDefault 메서드는 이러한 DOM 요소의 기본 동작을 중단시킨다.
40.8.2 이벤트 전파 방지
- 이벤트 객체의 stopPropagation 메서드는 이벤트 전파를 중지시킨다. 즉, 상위 DOM 요소에게 이벤트가 전파되는 것을 막는 다는 것이다.
40.9 이벤트 핸들러 내부의 this
40.9.1 이벤트 핸들러 어트리뷰트 방식
- 다음 예제의 handleClick 함수 내부의 this는 전역 객체 window를 가리킨다.
- 일반 함수로서 호출되는 함수 내부의 this는 전역 객체를 가리키기 때문
- 일반 함수로서 호출되는 함수 내부의 this는 전역 객체를 가리키기 때문
- 단, 이벤트 핸들러를 호출할 때 인수로 전달한 this는 이벤트를 바인딩한 DOM 요소를 가리킨다.
40.9.2 이벤트 핸들러 프로퍼티 방식과 addEventListener 메서드 방식
<!DOCTYPE html>
<html>
<head>
<body>
<button class="btn1">0</button>
<button class="btn2">0</button>
<script>
const $btn1 = document.querySelector('.btn1');
const $btn2 = document.querySelector('.btn2');
// 이벤트 핸들러 프로퍼티 방식
$btn1.onclick = function(e) {
console.log(this); // $btn1
console.log(e.currentTarget); // $btn1
console.log(this === e.currentTarget); // true
++this.textContent;
}
// 이벤트 리스너 메서드 방식
$btn2.addEventListener('click', function(e) {
console.log(this); // $btn2
console.log(e.currentTarget); // $btn2
console.log(this === e.currentTarget); // true
++this.textContent;
});
</script>
</body>
</html>
- 이벤트 핸들러 프로퍼티 방식과 addEventListener 메서드 방식 모두 이벤트 핸들러 내부의 this는 이벤트를 바인딩한 DOM 요소를 가리킨다.
- 즉, 이벤트 핸들러 내부의 this는 이벤트 객체의 currentTarget 프로퍼티와 같다.
- 화살표 함수로 정의한 이벤트 핸들러 내부의 this는 상위 스코프의 this를 가리킨다.
- 화살표 함수는 함수 자체의 this 바인딩을 갖지 않는다.
40.10 이벤트 핸들러에 인수 전달
- 이벤트 핸들러 어트리뷰트 방식은 함수 호출문을 사용할 수 있기 때문에 인수를 전달할 수 있다.
- 이벤트 핸들러 프로퍼티 방식과 addEventListener 메서드 방식의 경우 이벤트 핸들러를 브라우저가 호출하기 때문에 함수 호출문이 아닌 함수 자체를 등록하기 때문에 인수를 전달할 수 없다.
- 그러나 이벤트 핸들러 내부에서 함수를 호출하면서 인수를 전달할 수 있다.
-
<!DOCTYPE html> <html> <head> <body> <lable>User Name <input type="text"/></lable> <em class="message"></em> <script> const MIN_USER_NAME_LENGTH = 5; const $input = document.querySelector('input[type=text]'); const $msg = document.querySelector('.message'); const checkUserNameLength = min => { $msg.textContent = $input.value.length < min ? `이름은 ${min}자 이상으로 입력해 주세요` : ''; } // 이벤트 핸들러 내부에서 함수를 호출하면서 인수를 전달한다. $input.onblur = () => { checkUserNameLength(MIN_USER_NAME_LENGTH); } </script> </body> </html>
40.11 커스텀 이벤트
40.11.1 커스텀 이벤트 생성
- 개발자의 의도로 생성된 이벤트를 커스텀 이벤트라 한다.
- 이벤트 생성자 함수는 첫 번째 인수로 이벤트 타입을 나타내는 문자열을 전달받는다.
- 이때 이벤트 타입을 나타내는 문자열은 기존 이벤트 타입을 사용할 수도 있고, 임의의 문자열을 사용하여 새로운 이벤트 타입을 지정할 수도 있다.
- 이 경우 일반적으로 CustomEvent 이벤트 생성자 함수를 사용한다.
// KeyboardEvent 생성자 함수로 keyup 이벤트 타입의 커스텀 이벤트 객체를 생성
const keyboardEvent = new KeyboardEvent('keyup');
console.log(keyboardEvent.type); // keyup
// CustomEvent 생성자 함수로 foo 이벤트 타입의 커스텀 이벤트 객체를 생성
const customEvent = new CustomEvent('foo');
console.log(customEvent.type); // foo
40.11.2 커스텀 이벤트 디스패치
<!DOCTYPE html>
<html lang="kr">
<head>
<meta charset="UTF-8" />
<title>Practice</title>
</head>
<body>
<button class="btn">Click me</button>
<script>
const $button = document.querySelector('.btn');
$button.addEventListener('click', e => {
console.log(e) // MouseEvent {...}
alert(`${e} clicked!`);
});
// 커스텀 이벤트 생성
const customEvent = new MouseEvent('click');
// 커스텀 이벤트 디스패치(동기 처리). click 이벤트가 발생한다.
$button.dispatchEvent(customEvent);
</script>
</body>
</html>
- 생성된 커스텀 이벤트는 dispatchEvent 메서드로 디스패치(이벤트를 발생시키는 행위)할 수 있다.
- dispatchEvent 메서드에 이벤트 객체를 인수로 전달하면서 호출하면 인수로 전달한 이벤트 타입의 이벤트가 발생한다.
- 기존 타입이 아닌 임의의 이벤트 타입을 지정하여 커스텀 이벤트 객체를 생성한 경우 반드시addEventListener 메서드 방식으로 이벤트 핸들러를 등록해야 한다.
- 이벤트 핸들러 어트리뷰트/프로퍼티 방식으로 등록할 수 없는 이유는 on + 이벤트 타입으로 이루어진 이벤트 핸들러 어트리뷰트/프로퍼티가 요소 노드에 존재하지 않기 때문이다.
- ex. 'foo' 라는 임의의 이벤트 타입으로 커스텀 이벤트를 생성할 경우 'onfoo'라는 핸들러 어트리뷰트/프로퍼티가 요소 노드에 존재하지 않는다.
'개발 관련 도서' 카테고리의 다른 글
모던 자바스크립트 - REST API (0) | 2024.08.04 |
---|---|
모던 자바스크립트 - Ajax (0) | 2024.08.04 |
모던 자바스크립트 - DOM(2) (0) | 2024.07.30 |
모던 자바스크립트 - 브라우저의 렌더링 과정 (0) | 2024.07.21 |
모던 자바스크립트 - 스프레드 문법 (0) | 2024.07.14 |