2. 이벤트
2-1. 이벤트 기초
- 브라우저는 클릭, 마우스 이동, 키보드 입력 등이 일어나면 이를 감지하여 특정한 타입의 이벤트를 발생
- 만약 애플리케이션이 특정 이벤트에 반응하고 싶다면 이벤트에 대응하는 함수를 브라우저에게 알려주어 호출을 위임가능
-> 이 때 호출될 함수를 이벤트 핸들러
이벤트 타입
click
– 요소 위에서 마우스 왼쪽 버튼을 눌렀을 때(터치스크린이 있는 장치에선 탭 했을 때) 발생
dblclick
– 요소 위에서 마우스 왼쪽 버튼을 두번 빠르게 눌렀을 때 발생
contextmenu
– 요소 위에서 마우스 오른쪽 버튼을 눌렀을 때 발생합니다.
mouseover
와 mouseout
– 마우스 커서를 요소 위로 움직였을 때, 커서가 요소 밖으로 움직였을 때 발생
mousedown
과 mouseup
– 요소 위에서 마우스 왼쪽 버튼을 누르고 있을 때, 마우스 버튼을 뗄 때 발생합니다.
mousemove
– 마우스를 움직일 때 발생
keydown
과 keyup
– 사용자가 키보드 버튼을 누르거나 뗄 때 발생
-폼 요소 이벤트
submit
– 사용자가 <form>
을 제출할 때 발생
change
– 사용자가 <input>
과 같은 요소에 값이 변할 때 발생
focus
– 사용자가 <input>
과 같은 요소에 포커스 할 때 발생
blur
– 사용자가 <input>
과 같은 요소에 포커스를 해제할 때 발생
-기타 이벤트
resize
– 브라우저 창의 크기를 변경할 때 발생
scroll
– 웹페이지 또는 HTML요소를 스크롤할 때 연속적으로 발생
이벤트 핸들러
- 이벤트 핸들러란 특정 타입의 이벤트가 발생했을 때 브라우저가 실행하는 함수
-> 사용자가 만든 이벤트 처리 함수를 브라우저에게 위임
-> 총 3가지 방식이 있음!
- 어트리뷰트 방식
- 이벤트 핸들러를 HTML 요소에 직접 지정하는 방법
on + 이벤트 타입
으로 이루어진 속성명을 적고 속성값으로 이벤트 핸들러 함수의 호출문을 적음
- HTML과 자바스크립트의 분리를 위해 요즘은 사용 X
<div class="box"
onmouseleave="boxClickHandler()"
onmouseover="makeTextHandler()"></div>
<div class="box green" ondblclick="makeTextHandler()"></div>
<div class="box red" onmouseover="growHandler()"></div>
- 프로퍼티 방식
- 이벤트 핸들러를 요소 노드의 프로퍼티로 추가하는 방식
- HTML과 자바스크립트를 분리하여 코딩할 수 있다는 장점
- 같은 타입의 이벤트에는 여러 핸들러를 바인딩 할 수 없다는 단점
const $b1 = document.getElementById('b1');
$b1.onclick = sayHelloHandler;
const $b2 = document.getElementById('b2');
$b2.ondblclick = () => {
$b2.style.width = '150px';
};
const $b3 = document.getElementById('b3');
$b3.onmouseover = () => {
$b3.style.background = 'red';
};
$b3.onmouseleave = () => {
$b3.style.background = 'yellow';
};
- 콜백함수 방식
- addEventListener 메서드는 첫번째 인수로 이벤트 종류를 나타내는 문자열의 이벤트 타입을 전달 (어떤 이벤트를 할 것인지)
-> 이 때 접두사 on을 붙이지 않음 !! XXXXXXXX
- 두 번째 인수로는 이벤트 핸들러 함수를 콜백으로 전달 (이벤트가 발생했을 때 어떤 일이 일어날지)
-> 이 방법은 동일한 요소에서 동일한 이벤트에 대해 하나 이상의 이벤트 핸들러를 등록 가능
- 기존 핸들러를 지우고 싶다면 수동으로 지워야함
-> 단, 반드시 핸들러가 기명함수이어야 함 (이름이 있는 함수)
const $btn = document.getElementById('btn');
const helloHandler = () => alert('알룡??');
$btn.addEventListener('click', helloHandler);
$btn.removeEventListener('click', helloHandler);
$btn.addEventListener('click', () => {
$btn.style.background = 'aqua';
});
퀴즈 1
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.disappear {
display: none;
}
</style>
</head>
<body>
<button id="hider">텍스트 숨기기!!</button>
<div class="text">안녕하세요~~</div>
<script>
const $btn = document.getElementById("hider");
const $textBox = document.querySelector(".text");
$btn.addEventListener("click", () => {
if ($textBox.classList.contains("disappear")) {
$textBox.classList.remove("disappear");
$btn.textContent = "텍스트 숨기기!";
} else {
$textBox.classList.add("disappear");
$btn.textContent = "텍스트 보이기";
}
});
</script>
</body>
</html>
- 텍스트가 보인다면 버튼을 눌렀을 때 텍스트가 사라지면서 버튼의 text가 바뀌게함
- 텍스트가 안보인다면 버튼을 눌렀을 때 텍스트가 나타나면서 버튼의 text가 바뀌게함
퀴즈2
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.menu ul {
margin: 0;
list-style: none;
padding-left: 20px;
display: none;
}
.menu .title {
font-size: 18px;
cursor: pointer;
-ms-user-select: none;
-moz-user-select: -moz-none;
-khtml-user-select: none;
-webkit-user-select: none;
user-select: none;
}
.menu .title::before {
content: '▶ ';
font-size: 80%;
color: green;
}
.menu.open .title::before {
content: '▼ ';
}
.menu.open ul {
display: block;
}
</style>
</head>
<body>
<div id="lunches" class="menu">
<span class="title">추천 메뉴(Click Me!)</span>
<ul>
<li>돈까스</li>
<li>군만두</li>
<li>볶음밥</li>
<li>마파두부</li>
</ul>
</div>
<script>
const $lunches = document.getElementById('lunches');
const $title = $lunches.querySelector('.title');
$title.addEventListener('click', function () {
$lunches.classList.toggle('open');
});
</script>
</body>
</html>
- toggle 메서드를 통해 클릭했을 때 open 클래스가 없으면 추가, 있으면 삭제 시키면서 메뉴가 뜨게함
퀴즈3
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.dropdown {
width: fit-content;
margin: 0 auto;
position: relative;
}
.dropdown .btn {
padding: 10px 40px;
font-size: 20px;
background: brown;
color: wheat;
}
#drop-content {
display: none;
position: absolute;
z-index: 99;
}
#drop-content a {
display: block;
font-size: 20px;
background: #dfdfdf;
color: black;
text-decoration: none;
padding: 10px 36px;
margin-top: 2px;
}
#drop-content a:hover {
background: rgb(61, 60, 60);
color: #fff;
}
</style>
</head>
<body>
<div class="dropdown">
<button class="btn">Drop</button>
<div id="drop-content">
<a href="#">Menu1</a>
<a href="#">Menu2</a>
<a href="#">Menu3</a>
<a href="#">Menu4</a>
<a href="#">Menu5</a>
</div>
</div>
<script>
const $btn = document.querySelector(".btn");
const $drop_content = document.getElementById("drop-content");
$btn.addEventListener("mouseover", () => {
$drop_content.style.display = 'block';
});
$drop_content.parentElement.addEventListener("mouseleave", () => {
$drop_content.style.display = 'none';
});
</script>
</body>
</html>
- mouseover를 통해 마우스를 올리면 메뉴가 뜨고, mouseleave를 통해 마우스를 바깥으로 빼면 메뉴가 사라지게함
퀴즈4
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>실시간 배경색 변경</title>
</head>
<body>
<input
type="text"
id="colorInput"
placeholder="색상 이름이나 HEX 코드를 입력하세요"
/>
<div id="warning" style="color: red; display: none">
유효하지 않은 색상입니다!
</div>
<script>
const $input = document.getElementById("colorInput");
const $warning = document.getElementById("warning");
$input.addEventListener("input", () => {
document.body.style.background = $input.value;
if (
document.body.style.background !== $input.value || $input.value === "")
{
$warning.style.display = "block";
} else {
$warning.style.display = "none";
}
});
</script>
</body>
</html>
- change 이벤트는 입력이 끝났을 때 확인
- input 이벤트는 한 글자씩 입력할 때 마다 확인
- 전체에 색을 넣는 법 :
document.body.style.background