writed by hanryu1109
🔥 용어 설명
HTML
요소의 어트리뷰트 중에는 이벤트에 대응하는 Event Handler Attribute 가 있다.onclick과
같이 on 접두사와 이벤트의 종류를 이벤트 타입으로 이루어져 있다. (ex. onclick, onfocus)<!DOCTYPE html>
<html>
<body>
<button onclick="sayHi('Han')">클릭</button>
<!-- 함수 호출! -->
<script>
function sayHi(name) {
console.log(`Hi!, ${name}`);
}
</script>
</body>
</html>
잘 몰랐던 내용: p759
window
객체와 Document
, HTMLElement
타입의 DOM
노드 객체는 / 이벤트에 대응하는 이벤트 핸들러 프로퍼티를 가지고 있다.<!DOCTYPE html>
<html>
<body>
<button>클릭</button>
<script>
const $button = document.querySelector("button");
$button.onclick = function () {
console.log("button click!");
};
</script>
</body>
</html>
잘 몰랐던 내용: p761
EventTarget.prototype.addEventListener
메서드를 사용하여 이벤트 핸들러를 등록할 수 있다.<!DOCTYPE html>
<html>
<body>
<button>클릭</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>
🔥 주의!
동일한 HTML
요소에서 발생한 동일한 이벤트에 대해 1) 이벤트 핸들러 프로퍼티 방식과 2) addEventListener 메서드 방식을 모두 사용하여 이벤트 핸들러를 등록할 경우
=>>> addEventListener 메서드 방식은 이벤트 핸들러 프로퍼티에 바인딩된 이벤트 핸들러에 아무런 영향을 주지 않기 때문에 2개의 이벤트 핸들러가 모두 호출된다.
addEventListener 메서드 방식은 하나 이상의 이벤트 핸들러를 등록할 수 있다. 등록된 순서대로 호출된다.
단, addEventListener 메서드를 통해 참조가 동일한 이벤트 핸들러를 중복 등록하면 하나의 이벤트 핸들러만 등록된다.
<!DOCTYPE html>
<html>
<body>
<button>클릭</button>
<script>
const $button = document.querySelector("button");
const handleClick = () => console.log("button click!");
// 참조가 동일한 이벤트 핸들러를 중복 등록하면 하나의 핸들러만 등록된다.
$button.addEventListener("click", handleClick);
$button.addEventListener("click", handleClick);
</script>
</body>
</html>
addEventListener
메서드로 등록한 이벤트 핸들러를 제거하려면 EventTarget.prototype.removeEventListener
메서드를 사용한다.<!DOCTYPE html>
<html>
<body>
<button>클릭</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>
null
을 할당한다.잘 몰랐던 내용: 무명함수를 이벤트 핸들러로 등록한 경우 제거할 수 없다. p766
<!DOCTYPE html>
<html>
<body>
<p>클릭하세요. 클릭한 곳의 좌표가 표시됩니다.</p>
<em class="message"></em>
<script>
const $msg = document.querySelector(".message");
// 클릭 이벤트에 의해 생성된 이벤트 객체는 이벤트 핸들러의 첫 번째 인수로 전달된다.(브라우저가 이벤트 핸들러를 호출할 때 이벤트 객체를 인수로 전달한다)
function showCoords(e) {
$msg.textContent = `clientX: ${e.clientX}, clientT: ${e.clientY}`;
}
document.onclick = showCoords;
</script>
</body>
</html>
잘 몰랐던 내용:
event
가 아닌 다른 이름으로는 이벤트 객체를 전달하지 못한다! (p768)❓이런 정보를 가지고 무엇을 할 수 있을까? DOM 요소를 드래그하여 이동시켜야 할 때
잘 몰랐던 내용:
❓이런 정보를 가지고 무엇을 할 수 있을까? input 요소의 입력 필드에 엔터 키가 입력되면 현재까지 입력 필드에 입력된 값을 출력하는 예제를 만들어보자.
🔥 정의
이벤트 전파: DOM
트리 상에 존재하는 DOM
요소 노드에서 발생한 이벤트는 DOM
트리를 통해 전판된다. 이를 이벤트 전파(Event Propagation)라고 한다.
<!DOCTYPE html>
<html lang="en">
<body>
<ul id="fruits">
<li id="apple">apple</li>
<li id="banana">banana</li>
<li id="orange">orange</li>
</ul>
</body>
</html>
🔥 정의
이벤트 위임: 여러 개의 하위 DOM 요소에 각각 이벤트 핸들러를 등록하는 대신 하나의 상위 요소에 이벤트 핸들러를 등록하는 방법을 말한다.
DOM
요소에서도 캐치할 수 있다.DOM
요소에 이벤트 핸들러를 등록하면 여러 개의 하위 DOM
요소에 이벤트 핸들러를 등록할 필요가 없다.DOM
요소를 추가하더라도 일일이 추가된 DOM
요소에 이벤트 핸들러를 등록할 필요가 없다.DOM
요소는 저마다 기본 동작이 있다. 예를 들어, a 요소를 클릭하면 href 어트리뷰트에 지정된 링크로 이동하고, checkbox 또는 radio 요소를 클릭하면 체크 또는 해제된다.preventDefault
메서드는 이러한 DOM
요소의 기본동작을 중단시킨다.stopPropagation
메서드는 이벤트 전파를 중지시킨다.stopPropagation
메서드는 하위 DOM
요소의 이벤트를 개별적으로 처리하기 이벤트의 전파를 중단시킨다.함수에 인수를 전달하려면 함수를 호출할 때 전달해야 한다.
그럼 어떻게 해야 전달할 수 있을까?
=> 이벤트 핸들러 내부에서 함수를 호출하면서 인수를 전달할 수 있다.
=> 또는 이벤트 핸들러를 반환하는 함수를 호출하면서 인수를 전달할 수 있다.
<!DOCTYPE html>
<html lang="en">
<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 lang="en">
<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>
Event
, UIEvent
, MouseEvent
같은 이벤트 생성자 함수를 호출하여 명시적으로 생성한 이벤트 객체는 임의의 이벤트 타입을 지정할 수 있다.‼️ 잘몰랐던 내용
CustomEvent
이벤트 생성자 함수를 사용한다.dispatchEvent
메서드로 디스패치(이벤트를 발생시키는 행위)할 수 있다.dispatchEvent
메서드에 이벤트 객체를 인수로 전달하면서 호출하면 인수로 전달한 이벤트 타입의 이벤트가 발생한다.