<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
// 사용자가 버튼을 클릭하면 함수를 호출하도록 요청
$button.onclick = () => { alert('button click'); };
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<button onclick="sayHi('Lee')">Click me!</button>
<script>
function sayHi(name) {
console.log(`Hi! ${name}.`);
}
</script>
</body>
</html>
function onclick(event) {
sayHi('Lee');
}
<!-- 이벤트 핸들러에 인수를 전달하기 곤란하다. -->
<button onclick="sayHi">Click me!</button>
<button onclick="console.log('Hi! '); console.log('Lee');">Click me!</button>
<!-- Angular -->
<button (click)="handleClick($event)">Save</button>
{ /* React */ }
<button onClick={handleClick}>Save</button>
<!-- Svelte -->
<button on:click={handleClick}>Save</button>
<!-- Vue.js -->
<button v-on:click="handleClick($event)">Save</button>
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
// 이벤트 핸들러 프로퍼티에 이벤트 핸들러를 바인딩
$button.onclick = function () {
console.log('button click');
};
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
// 이벤트 핸들러 프로퍼티 방식은 하나의 이벤트에 하나의 이벤트 핸들러만을 바인딩할 수 있다.
// 첫 번째로 바인딩된 이벤트 핸들러는 두 번째 바인딩된 이벤트 핸들러에 의해 재할당되어
// 실행되지 않는다.
$button.onclick = function () {
console.log('Button clicked 1');
};
// 두 번째로 바인딩된 이벤트 핸들러
$button.onclick = function () {
console.log('Button clicked 2');
};
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
// 이벤트 핸들러 프로퍼티 방식
// $button.onclick = function () {
// console.log('button click');
// };
// addEventListener 메서드 방식
$button.addEventListener('click', function () {
console.log('button click');
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
// 이벤트 핸들러 프로퍼티 방식
$button.onclick = function () {
console.log('[이벤트 핸들러 프로퍼티 방식]button click');
};
// addEventListener 메서드 방식
$button.addEventListener('click', function () {
console.log('[addEventListener 메서드 방식]button click');
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
// addEventListener 메서드는 동일한 요소에서 발생한 동일한 이벤트에 대해
// 하나 이상의 이벤트 핸들러를 등록할 수 있다.
$button.addEventListener('click', function () {
console.log('[1]button click');
});
$button.addEventListener('click', function () {
console.log('[2]button click');
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
const handleClick = () => console.log('button click');
// 참조가 동일한 이벤트 핸들러를 중복 등록하면 하나의 핸들러만 등록된다.
$button.addEventListener('click', handleClick);
$button.addEventListener('click', handleClick);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
const handleClick = () => console.log('button click');
// 이벤트 핸들러 등록
$button.addEventListener('click', handleClick);
// 이벤트 핸들러 제거
// addEventListener 메서드에 전달한 인수와 removeEventListener 메서드에
// 전달한 인수가 일치하지 않으면 이벤트 핸들러가 제거되지 않는다.
$button.removeEventListener('click', handleClick, true); // 실패
$button.removeEventListener('click', handleClick); // 성공
</script>
</body>
</html>
// 이벤트 핸들러 등록
$button.addEventListener('click', () => console.log('button click'));
// 등록한 이벤트 핸들러를 참조할 수 없으므로 제거할 수 없다.
// 기명 함수를 이벤트 핸들러로 등록
$button.addEventListener('click', function foo() {
console.log('button click');
// 이벤트 핸들러를 제거한다. 따라서 이벤트 핸들러는 단 한 번만 호출된다.
$button.removeEventListener('click', foo);
});
// 무명 함수를 이벤트 핸들러로 등록
$button.addEventListener('click', function () {
console.log('button click');
// 이벤트 핸들러를 제거한다. 따라서 이벤트 핸들러는 단 한 번만 호출된다.
// arguments.callee는 호출된 함수, 즉 함수 자신을 가리킨다.
$button.removeEventListener('click', arguments.callee);
});
<!DOCTYPE html>
<html>
<body>
<button>Click me!</button>
<script>
const $button = document.querySelector('button');
const handleClick = () => console.log('button click');
// 이벤트 핸들러 프로퍼티 방식으로 이벤트 핸들러 등록
$button.onclick = handleClick;
// removeEventListener 메서드로 이벤트 핸들러를 제거할 수 없다.
$button.removeEventListener('click', handleClick);
// 이벤트 핸들러 프로퍼티에 null을 할당하여 이벤트 핸들러를 제거한다.
$button.onclick = null;
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<p>클릭하세요. 클릭한 곳의 좌표가 표시됩니다.</p>
<em class="message"></em>
<script>
const $msg = document.querySelector('.message');
// 클릭 이벤트에 의해 생성된 이벤트 객체는 이벤트 핸들러의 첫 번째 인수로 전달된다.
function showCoords(e) {
$msg.textContent = `clientX: ${e.clientX}, clientY: ${e.clientY}`;
}
document.onclick = showCoords;
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<style>
html, body { height: 100%; }
</style>
</head>
<!-- 이벤트 핸들러 어트리뷰트 방식의 경우 event가 아닌 다른 이름으로는 이벤트 객체를
전달받지 못한다. -->
<body onclick="showCoords(event)">
<p>클릭하세요. 클릭한 곳의 좌표가 표시됩니다.</p>
<em class="message"></em>
<script>
const $msg = document.querySelector('.message');
// 클릭 이벤트에 의해 생성된 이벤트 객체는 이벤트 핸들러의 첫 번째 인수로 전달된다.
function showCoords(e) {
$msg.textContent = `clientX: ${e.clientX}, clientY: ${e.clientY}`;
}
</script>
</body>
</html>
function onclick(event) {
showCoords(event);
}
<!DOCTYPE html>
<html>
<body>
<script>
// Event 생성자 함수를 호출하여 foo 이벤트 타입의 Event 객체를 생성한다.
let e = new Event('foo');
console.log(e);
// Event {isTrusted: false, type: "foo", target: null, ...}
console.log(e.type); // "foo"
console.log(e instanceof Event); // true
console.log(e instanceof Object); // true
// FocusEvent 생성자 함수를 호출하여 focus 이벤트 타입의 FocusEvent 객체를 생성한다.
e = new FocusEvent('focus');
console.log(e);
// FocusEvent {isTrusted: false, relatedTarget: null, view: null, ...}
// MouseEvent 생성자 함수를 호출하여 click 이벤트 타입의 MouseEvent 객체를 생성한다.
e = new MouseEvent('click');
console.log(e);
// MouseEvent {isTrusted: false, screenX: 0, screenY: 0, clientX: 0, ... }
// KeyboardEvent 생성자 함수를 호출하여 keyup 이벤트 타입의 KeyboardEvent 객체를
// 생성한다.
e = new KeyboardEvent('keyup');
console.log(e);
// KeyboardEvent {isTrusted: false, key: "", code: "", ctrlKey: false, ...}
// InputEvent 생성자 함수를 호출하여 change 이벤트 타입의 InputEvent 객체를 생성한다.
e = new InputEvent('change');
console.log(e);
// InputEvent {isTrusted: false, data: null, inputType: "", ...}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<input type="text">
<input type="checkbox">
<button>Click me!</button>
<script>
const $input = document.querySelector('input[type=text]');
const $checkbox = document.querySelector('input[type=checkbox]');
const $button = document.querySelector('button');
// load 이벤트가 발생하면 Event 타입의 이벤트 객체가 생성된다.
window.onload = console.log;
// change 이벤트가 발생하면 Event 타입의 이벤트 객체가 생성된다.
$checkbox.onchange = console.log;
// focus 이벤트가 발생하면 FocusEvent 타입의 이벤트 객체가 생성된다.
$input.onfocus = console.log;
// input 이벤트가 발생하면 InputEvent 타입의 이벤트 객체가 생성된다.
$input.oninput = console.log;
// keyup 이벤트가 발생하면 KeyboardEvent 타입의 이벤트 객체가 생성된다.
$input.onkeyup = console.log;
// click 이벤트가 발생하면 MouseEvent 타입의 이벤트 객체가 생성된다.
$button.onclick = console.log;
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<input type="checkbox">
<em class="message">off</em>
<script>
const $checkbox = document.querySelector('input[type=checkbox]');
const $msg = document.querySelector('.message');
// change 이벤트가 발생하면 Event 타입의 이벤트 객체가 생성된다.
$checkbox.onchange = e => {
console.log(Object.getPrototypeOf(e) === Event.prototype); // true
// e.target은 change 이벤트를 발생시킨 DOM 요소 $checkbox를 가리키고
// e.target.checked는 체크박스 요소의 현재 체크 상태를 나타낸다.
$msg.textContent = e.target.checked ? 'on' : 'off';
};
</script>
</body>
</html>
$checkbox.onchange = e => {
// e.target은 change 이벤트를 발생시킨 DOM 요소 $checkbox를 가리키고
// e.currentTarget은 이벤트 핸들러가 바인딩된 DOM 요소 $checkbox를 가리킨다.
console.log(e.target === e.currentTarget); // true
$msg.textContent = e.target.checked ? 'on' : 'off';
};
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px;
height: 100px;
background-color: #fff700;
border: 5px solid orange;
cursor: pointer;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
// 드래그 대상 요소
const $box = document.querySelector('.box');
// 드래그 시작 시점의 마우스 포인터 위치
const initialMousePos = { x: 0, y: 0 };
// 오프셋: 이동할 거리
const offset = { x: 0, y: 0 };
// mousemove 이벤트 핸들러
const move = e => {
// 오프셋 = 현재(드래그하고 있는 시점) 마우스 포인터 위치 - 드래그 시작 시점의 마우스 포인터 위치
offset.x = e.clientX - initialMousePos.x;
offset.y = e.clientY - initialMousePos.y;
// translate3d는 GPU를 사용하므로 absolute의 top, left를 사용하는 것보다 빠르다.
// top, left는 레이아웃에 영향을 준다.
$box.style.transform = `translate3d(${offset.x}px, ${offset.y}px, 0)`;
};
// mousedown 이벤트가 발생하면 드래그 시작 시점의 마우스 포인터 좌표를 저장한다.
$box.addEventListener('mousedown', e => {
// 이동 거리를 계산하기 위해 mousedown 이벤트가 발생(드래그를 시작)하면
// 드래그 시작 시점의 마우스 포인터 좌표(e.clientX/e.clientY: 뷰포트 상에서 현재
// 마우스의 포인터 좌표)를 저장해 둔다. 한번 이상 드래그로 이동한 경우 move에서
// translate3d(${offset.x}px, ${offset.y}px, 0)으로 이동한 상태이므로
// offset.x와 offset.y를 빼주어야 한다.
initialMousePos.x = e.clientX - offset.x;
initialMousePos.y = e.clientY - offset.y;
// mousedown 이벤트가 발생한 상태에서 mousemove 이벤트가 발생하면
// box 요소를 이동시킨다.
document.addEventListener('mousemove', move);
});
// mouseup 이벤트가 발생하면 mousemove 이벤트를 제거해 이동을 멈춘다.
document.addEventListener('mouseup', () => {
document.removeEventListener('mousemove', move);
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<input type="text" />
<em class="message"></em>
<script>
const $input = document.querySelector('input[type=text]');
const $msg = document.querySelector('.message');
$input.onkeyup = e => {
// e.key는 입력한 키 값을 문자열로 반환한다.
// 입력한 키가 'Enter', 즉 엔터 키가 아니면 무시한다.
if (e.key !== 'Enter') return;
// 엔터키가 입력되면 현재까지 입력 필드에 입력된 값을 출력한다.
$msg.textContent = e.target.value;
e.target.value = '';
};
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
<li id="apple">Apple</li>
<li id="banana">Banana</li>
<li id="orange">Orange</li>
</ul>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
<li id="apple">Apple</li>
<li id="banana">Banana</li>
<li id="orange">Orange</li>
</ul>
<script>
const $fruits = document.getElementById('fruits');
// #fruits 요소의 하위 요소인 li 요소를 클릭한 경우
$fruits.addEventListener('click', e => {
console.log(`이벤트 단계: ${e.eventPhase}`); // 3: 버블링 단계
console.log(`이벤트 타깃: ${e.target}`); // [object HTMLLIElement]
console.log(`커런트 타깃: ${e.currentTarget}`); // [object HTMLUListElement]
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
<li id="apple">Apple</li>
<li id="banana">Banana</li>
<li id="orange">Orange</li>
</ul>
<script>
const $fruits = document.getElementById('fruits');
const $banana = document.getElementById('banana');
// #fruits 요소의 하위 요소인 li 요소를 클릭한 경우
// 캡처링 단계의 이벤트를 캐치한다.
$fruits.addEventListener('click', e => {
console.log(`이벤트 단계: ${e.eventPhase}`); // 1: 캡처링 단계
console.log(`이벤트 타깃: ${e.target}`); // [object HTMLLIElement]
console.log(`커런트 타깃: ${e.currentTarget}`); // [object HTMLUListElement]
}, true);
// 타깃 단계의 이벤트를 캐치한다.
$banana.addEventListener('click', e => {
console.log(`이벤트 단계: ${e.eventPhase}`); // 2: 타깃 단계
console.log(`이벤트 타깃: ${e.target}`); // [object HTMLLIElement]
console.log(`커런트 타깃: ${e.currentTarget}`); // [object HTMLLIElement]
});
// 버블링 단계의 이벤트를 캐치한다.
$fruits.addEventListener('click', e => {
console.log(`이벤트 단계: ${e.eventPhase}`); // 3: 버블링 단계
console.log(`이벤트 타깃: ${e.target}`); // [object HTMLLIElement]
console.log(`커런트 타깃: ${e.currentTarget}`); // [object HTMLUListElement]
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<style>
html, body { height: 100%; }
</style>
<body>
<p>버블링과 캡처링 이벤트 <button>버튼</button></p>
<script>
// 버블링 단계의 이벤트를 캐치
document.body.addEventListener('click', () => {
console.log('Handler for body.');
});
// 캡처링 단계의 이벤트를 캐치
document.querySelector('p').addEventListener('click', () => {
console.log('Handler for paragraph.');
}, true);
// 타깃 단계의 이벤트를 캐치
document.querySelector('button').addEventListener('click', () => {
console.log('Handler for button.');
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<style>
#fruits {
display: flex;
list-style-type: none;
padding: 0;
}
#fruits li {
width: 100px;
cursor: pointer;
}
#fruits .active {
color: red;
text-decoration: underline;
}
</style>
</head>
<body>
<nav>
<ul id="fruits">
<li id="apple" class="active">Apple</li>
<li id="banana">Banana</li>
<li id="orange">Orange</li>
</ul>
</nav>
<div>선택된 내비게이션 아이템: <em class="msg">apple</em></div>
<script>
const $fruits = document.getElementById('fruits');
const $msg = document.querySelector('.msg');
// 사용자 클릭에 의해 선택된 내비게이션 아이템(li 요소)에 active 클래스를 추가하고
// 그 외의 모든 내비게이션 아이템의 active 클래스를 제거한다.
function activate({ target }) {
[...$fruits.children].forEach($fruit => {
$fruit.classList.toggle('active', $fruit === target);
$msg.textContent = target.id;
});
}
// 모든 내비게이션 아이템(li 요소)에 이벤트 핸들러를 등록한다.
document.getElementById('apple').onclick = activate;
document.getElementById('banana').onclick = activate;
document.getElementById('orange').onclick = activate;
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<style>
#fruits {
display: flex;
list-style-type: none;
padding: 0;
}
#fruits li {
width: 100px;
cursor: pointer;
}
#fruits .active {
color: red;
text-decoration: underline;
}
</style>
</head>
<body>
<nav>
<ul id="fruits">
<li id="apple" class="active">Apple</li>
<li id="banana">Banana</li>
<li id="orange">Orange</li>
</ul>
</nav>
<div>선택된 내비게이션 아이템: <em class="msg">apple</em></div>
<script>
const $fruits = document.getElementById('fruits');
const $msg = document.querySelector('.msg');
// 사용자 클릭에 의해 선택된 내비게이션 아이템(li 요소)에 active 클래스를 추가하고
// 그 외의 모든 내비게이션 아이템의 active 클래스를 제거한다.
function activate({ target }) {
// 이벤트를 발생시킨 요소(target)가 ul#fruits의 자식 요소가 아니라면 무시한다.
if (!target.matches('#fruits > li')) return;
[...$fruits.children].forEach($fruit => {
$fruit.classList.toggle('active', $fruit === target);
$msg.textContent = target.id;
});
}
// 이벤트 위임: 상위 요소(ul#fruits)는 하위 요소의 이벤트를 캐치할 수 있다.
$fruits.onclick = activate;
</script>
</body>
</html>
function activate({ target }) {
// 이벤트를 발생시킨 요소(target)이 ul#fruits의 자식 요소가 아니라면 무시한다.
if (!target.matches('#fruits > li')) return;
...
$fruits.onclick = activate;
<!DOCTYPE html>
<html>
<body>
<a href="https://www.google.com">go</a>
<input type="checkbox">
<script>
document.querySelector('a').onclick = e => {
// a 요소의 기본 동작을 중단한다.
e.preventDefault();
};
document.querySelector('input[type=checkbox]').onclick = e => {
// checkbox 요소의 기본 동작을 중단한다.
e.preventDefault();
};
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<div class="container">
<button class="btn1">Button 1</button>
<button class="btn2">Button 2</button>
<button class="btn3">Button 3</button>
</div>
<script>
// 이벤트 위임. 클릭된 하위 버튼 요소의 color를 변경한다.
document.querySelector('.container').onclick = ({ target }) => {
if (!target.matches('.container > button')) return;
target.style.color = 'red';
};
// .btn2 요소는 이벤트를 전파하지 않으므로 상위 요소에서 이벤트를 캐치할 수 없다.
document.querySelector('.btn2').onclick = e => {
e.stopPropagation(); // 이벤트 전파 중단
e.target.style.color = 'blue';
};
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<button onclick="handleClick()">Click me</button>
<script>
function handleClick() {
console.log(this); // window
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<button onclick="handleClick(this)">Click me</button>
<script>
function handleClick(button) {
console.log(button); // 이벤트를 바인딩한 button 요소
console.log(this); // window
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<button class="btn1">0</button>
<button class="btn2">0</button>
<script>
const $button1 = document.querySelector('.btn1');
const $button2 = document.querySelector('.btn2');
// 이벤트 핸들러 프로퍼티 방식
$button1.onclick = function (e) {
// this는 이벤트를 바인딩한 DOM 요소를 가리킨다.
console.log(this); // $button1
console.log(e.currentTarget); // $button1
console.log(this === e.currentTarget); // true
// $button1의 textContent를 1 증가시킨다.
++this.textContent;
};
// addEventListener 메서드 방식
$button2.addEventListener('click', function (e) {
// this는 이벤트를 바인딩한 DOM 요소를 가리킨다.
console.log(this); // $button2
console.log(e.currentTarget); // $button2
console.log(this === e.currentTarget); // true
// $button2의 textContent를 1 증가시킨다.
++this.textContent;
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<button class="btn1">0</button>
<button class="btn2">0</button>
<script>
const $button1 = document.querySelector('.btn1');
const $button2 = document.querySelector('.btn2');
// 이벤트 핸들러 프로퍼티 방식
$button1.onclick = e => {
// 화살표 함수 내부의 this는 상위 스코프의 this를 가리킨다.
console.log(this); // window
console.log(e.currentTarget); // $button1
console.log(this === e.currentTarget); // false
// this는 window를 가리키므로 window.textContent에 NaN(undefined + 1)을 할당한다.
++this.textContent;
};
// addEventListener 메서드 방식
$button2.addEventListener('click', e => {
// 화살표 함수 내부의 this는 상위 스코프의 this를 가리킨다.
console.log(this); // window
console.log(e.currentTarget); // $button2
console.log(this === e.currentTarget); // false
// this는 window를 가리키므로 window.textContent에 NaN(undefined + 1)을 할당한다.
++this.textContent;
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<button class="btn">0</button>
<script>
class App {
constructor() {
this.$button = document.querySelector('.btn');
this.count = 0;
// increase 메서드를 이벤트 핸들러로 등록
this.$button.onclick = this.increase;
}
increase() {
// 이벤트 핸들러 increase 내부의 this는 DOM 요소(this.$button)를 가리킨다.
// 따라서 this.$button은 this.$button.$button과 같다.
this.$button.textContent = ++this.count;
// -> TypeError: Cannot set property 'textContent' of undefined
}
}
new App();
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<button class="btn">0</button>
<script>
class App {
constructor() {
this.$button = document.querySelector('.btn');
this.count = 0;
// increase 메서드를 이벤트 핸들러로 등록
// this.$button.onclick = this.increase;
// increase 메서드 내부의 this가 인스턴스를 가리키도록 한다.
this.$button.onclick = this.increase.bind(this);
}
increase() {
this.$button.textContent = ++this.count;
}
}
new App();
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<button class="btn">0</button>
<script>
class App {
constructor() {
this.$button = document.querySelector('.btn');
this.count = 0;
// 화살표 함수인 increase를 이벤트 핸들러로 등록
this.$button.onclick = this.increase;
}
// 클래스 필드 정의
// increase는 인스턴스 메서드이며 내부의 this는 인스턴스를 가리킨다.
increase = () => this.$button.textContent = ++this.count;
}
new App();
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<label>User name <input type='text'></label>
<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>
<!DOCTYPE html>
<html>
<body>
<label>User name <input type='text'></label>
<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 => e => {
$msg.textContent
= $input.value.length < min ? `이름은 ${min}자 이상 입력해 주세요` : '';
};
// 이벤트 핸들러를 반환하는 함수를 호출하면서 인수를 전달한다.
$input.onblur = checkUserNameLength(MIN_USER_NAME_LENGTH);
</script>
</body>
</html>
// KeyboardEvent 생성자 함수로 keyup 이벤트 타입의 커스텀 이벤트 객체를 생성
const keyboardEvent = new KeyboardEvent('keyup');
console.log(keyboardEvent.type); // keyup
// CustomEvent 생성자 함수로 foo 이벤트 타입의 커스텀 이벤트 객체를 생성
const customEvent = new CustomEvent('foo');
console.log(customEvent.type); // foo
// MouseEvent 생성자 함수로 click 이벤트 타입의 커스텀 이벤트 객체를 생성
const customEvent = new MouseEvent('click');
console.log(customEvent.type); // click
console.log(customEvent.bubbles); // false
console.log(customEvent.cancelable); // false
// MouseEvent 생성자 함수로 click 이벤트 타입의 커스텀 이벤트 객체를 생성
const customEvent = new MouseEvent('click', {
bubbles: true,
cancelable: true
});
console.log(customEvent.bubbles); // true
console.log(customEvent.cancelable); // true
// MouseEvent 생성자 함수로 click 이벤트 타입의 커스텀 이벤트 객체를 생성
const mouseEvent = new MouseEvent('click', {
bubbles: true,
cancelable: true,
clientX: 50,
clientY: 100
});
console.log(mouseEvent.clientX); // 50
console.log(mouseEvent.clientY); // 100
// KeyboardEvent 생성자 함수로 keyup 이벤트 타입의 커스텀 이벤트 객체를 생성
const keyboardEvent = new KeyboardEvent('keyup', { key: 'Enter' });
console.log(keyboardEvent.key); // Enter
// InputEvent 생성자 함수로 foo 이벤트 타입의 커스텀 이벤트 객체를 생성
const customEvent = new InputEvent('foo');
console.log(customEvent.isTrusted); // false
<!DOCTYPE html>
<html>
<body>
<button class="btn">Click me</button>
<script>
const $button = document.querySelector('.btn');
// 버튼 요소에 click 커스텀 이벤트 핸들러를 등록
// 커스텀 이벤트를 디스패치하기 이전에 이벤트 핸들러를 등록해야 한다.
$button.addEventListener('click', e => {
console.log(e); // MouseEvent {isTrusted: false, screenX: 0, ...}
alert(`${e} Clicked!`);
});
// 커스텀 이벤트 생성
const customEvent = new MouseEvent('click');
// 커스텀 이벤트 디스패치(동기 처리). click 이벤트가 발생한다.
$button.dispatchEvent(customEvent);
</script>
</body>
</html>
// CustomEvent 생성자 함수로 foo 이벤트 타입의 커스텀 이벤트 객체를 생성
const customEvent = new CustomEvent('foo');
console.log(customEvent.type); // foo
<!DOCTYPE html>
<html>
<body>
<button class="btn">Click me</button>
<script>
const $button = document.querySelector('.btn');
// 버튼 요소에 foo 커스텀 이벤트 핸들러를 등록
// 커스텀 이벤트를 디스패치하기 이전에 이벤트 핸들러를 등록해야 한다.
$button.addEventListener('foo', e => {
// e.detail에는 CustomEvent 함수의 두 번째 인수로 전달한 정보가 담겨 있다.
alert(e.detail.message);
});
// CustomEvent 생성자 함수로 foo 이벤트 타입의 커스텀 이벤트 객체를 생성
const customEvent = new CustomEvent('foo', {
detail: { message: 'Hello' } // 이벤트와 함께 전달하고 싶은 정보
});
// 커스텀 이벤트 디스패치
$button.dispatchEvent(customEvent);
</script>
</body>
</html>