//이벤트, Event
- 사건
- 객체(혹은 태그)에서 발생하는 사건
- 언제 발생할지 예측 불가능(시간)
// JavaScript Event Handling★★
- 이벤트 등록(구현)
- 사건 처리
- 언제 발생할지 예측 불가능한 사건에 대해 처리를 하고 싶다. > 언젠가 사건이 발생하면 처리하기 위한 코드를 미리 준비한다. > 사건과 연결 > 이벤트 처리, 이벤트 매핑, 이벤트 구현 등
1. 정적
- HTML 코드에 직접 사용
2. 동적
- JavaScript 코드를 사용
- this: 이벤트 주체(이벤트가 걸린 태그)
※ 함수 내의 this는 window 객체(전역 객체)를 말한다.
<!DOCTYPE html>
<html lang="en">
<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>
form > input {
display: block;
margin-bottom: 5px;
padding: 5px;
}
</style>
</head>
<body>
<h1>Event</h1>
<form name="form1">
<input type="text" name="txt1">
<input type="button" value="확인(정적이벤트)" name="btn1" onclick="window.document.form1.txt1.value = '홍길동';"> <!--1. 정적-->
<input type="button" value="확인(동적이벤트)" name="btn2">
</form>
<script>
// 2. 동적
window.document.form1.btn2.onclick = m1; // ()없음! 호출xx / 함수 포인터 > 언젠가는 찾아가서 실행
function m1() {
window.document.form1.txt1.value = '아무개';
}
</script>
</body>
</html>
// 마우스 관련 이벤트
- onmouseXXX
1. onmouseover(= onmouseenter)
- 해당 객체의 영역에 마우스(커서)가 진입하는 순간 발생
2. onmouseout(= onmouseleave)
- 해당 객체의 영역에서 마우스(커서)가 빠져나가는 순간 발생
3. onmousedown
- 해당 객체의 영역에서 마우스 버튼을 누르는 순간 발생
4. onmouseup
- 해당 객체의 영역에서 마우스 버튼을 떼는 순간 발생
5. onmousemove
- 해당 객체의 영역에서 마우스가 움직일 때마다 발생
~ event.buttons: 마우스 버튼의 번호
- 왼쪽(1), 오른쪽(2), 왼쪽+오른쪽(3), 휠버튼(4)
~ 마우스 커서 좌표
1. x, y
- 문서 좌측 상단을 기준으로 한다.
- 비표준(MS-IE) > 비권장
2. clientX, clientY★★★★★
- 문서 좌측 상단을 기준으로 한다.
- 표준 > 권장
≒ CSS > position: absolute;
3. screenX, screenY
- 모니터 좌측 상단을 기준
- 일상적으로는 다루기가 힘들다.
4. offsetX, offsetY★★★★★
- 이벤트 객체의 좌측 상단을 기준
- 자기 자신이 기준이 된다.
≒ CSS > position: relative;
~ event.target, event.srcElement : 눌린 버튼의 프로퍼티 제공
* onclick: 클릭했을 때 나타나는 이벤트
* onchange: 입력 컨트롤의 값이 변할 때 발생하는 이벤트
* oninput: 입력 컨트롤의 값이 변하는 것을 실시간으로 보여주는 이벤트
- onmouseover, onmouseout
<!DOCTYPE html>
<html lang="en">
<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>
textarea, input {
display: block;
margin-bottom: 10px;
}
textarea {
width: 500px;
height: 300px;
outline: none;
resize: none;
}
</style>
</head>
<body>
<h1>마우스 관련 이벤트</h1>
<form name="form1">
<textarea name="txt1"></textarea>
<input type="button" value="확인" name="btn1">
</form>
<script>
function message(txt) {
var now = new Date();
txt1.value = txt + '-' + now.toLocaleTimeString() + '\r\n' + txt1.value;
}
var txt1 = window.document.form1.txt1;
var txt2 = window.document.form1.btn1;
txt1.onmouseover = m1;
function m1() {
message('mouseover');
}
txt1.onmouseout = m2;
function m2() {
message('mouseout');
}
</script>
</body>
</html>
- onmousedown / onmouseup
<!DOCTYPE html>
<html lang="en">
<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>
textarea, input {
display: block;
margin-bottom: 10px;
}
textarea {
width: 500px;
height: 300px;
outline: none;
resize: none;
}
</style>
</head>
<body>
<h1>마우스 관련 이벤트</h1>
<form name="form1">
<textarea name="txt1"></textarea>
<input type="button" value="확인" name="btn1">
</form>
<script>
function message(txt) {
var now = new Date();
txt1.value = txt + '-' + now.toLocaleTimeString() + '\r\n' + txt1.value;
}
var txt1 = window.document.form1.txt1;
var txt2 = window.document.form1.btn1;
txt1.onmousedown = m3;
function m3() {
message('messagedown');
}
txt1.onmouseup = m4;
function m4() {
message('messageup');
}
</script>
</body>
</html>
- onmousemove
<!DOCTYPE html>
<html lang="en">
<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>
textarea, input {
display: block;
margin-bottom: 10px;
}
textarea {
width: 500px;
height: 300px;
outline: none;
resize: none;
}
</style>
</head>
<body>
<h1>마우스 관련 이벤트</h1>
<form name="form1">
<textarea name="txt1"></textarea>
<input type="button" value="확인" name="btn1">
</form>
<script>
function message(txt) {
var now = new Date();
txt1.value = txt + '-' + now.toLocaleTimeString() + '\r\n' + txt1.value;
}
var txt1 = window.document.form1.txt1;
var txt2 = window.document.form1.btn1;
var n = 1;
txt1.onmousemove = m5;
function m5() {
message('messagemove - ' + n);
n++
}
</script>
</body>
</html>
- event.buttons
<!DOCTYPE html>
<html lang="en">
<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>
textarea, input {
display: block;
margin-bottom: 10px;
}
textarea {
width: 500px;
height: 300px;
outline: none;
resize: none;
}
</style>
</head>
<body>
<h1>마우스 관련 이벤트</h1>
<form name="form1">
<textarea name="txt1"></textarea>
<input type="button" value="확인" name="btn1">
</form>
<script>
function message(txt) {
var now = new Date();
txt1.value = txt + '-' + now.toLocaleTimeString() + '\r\n' + txt1.value;
}
var txt1 = window.document.form1.txt1;
var txt2 = window.document.form1.btn1;
txt1.onmousedown = m3;
function m3() {
// message(event.buttons); //마우스 어떤 버튼인지 알 수 있다.
if(event.buttons == 2) {
alert('오른쪽 버튼 클릭 금지');
}
}
</script>
</body>
</html>
- x, y
<!DOCTYPE html>
<html lang="en">
<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>
textarea, input {
display: block;
margin-bottom: 10px;
}
textarea {
width: 500px;
height: 300px;
outline: none;
resize: none;
}
</style>
</head>
<body>
<h1>마우스 관련 이벤트</h1>
<form name="form1">
<textarea name="txt1"></textarea>
<input type="button" value="확인" name="btn1">
</form>
<script>
function message(txt) {
var now = new Date();
txt1.value = txt + '-' + now.toLocaleTimeString() + '\r\n' + txt1.value;
}
var txt1 = window.document.form1.txt1;
var txt2 = window.document.form1.btn1;
txt1.onmousedown = m3;
function m3() {
message(event.x + ',' + event.y);
}
</script>
</body>
</html>
- offsetX, offsetY
<!DOCTYPE html>
<html lang="en">
<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>
textarea, input {
display: block;
margin-bottom: 10px;
}
textarea {
width: 500px;
height: 300px;
outline: none;
resize: none;
}
</style>
</head>
<body>
<h1>마우스 관련 이벤트</h1>
<form name="form1">
<textarea name="txt1"></textarea>
<input type="button" value="확인" name="btn1">
</form>
<script>
function message(txt) {
var now = new Date();
txt1.value = txt + '-' + now.toLocaleTimeString() + '\r\n' + txt1.value;
}
var txt1 = window.document.form1.txt1;
var txt2 = window.document.form1.btn1;
txt1.onmousedown = m3;
function m3() {
message(event.offsetX + ',' + event.offsetY);
}
</script>
</body>
</html>
// onclick
- 마우스를 클릭할 때 발생하는 이벤트
<!DOCTYPE html>
<html lang="en">
<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>
textarea, input {
display: block;
margin-bottom: 10px;
}
textarea {
width: 500px;
height: 300px;
outline: none;
resize: none;
}
</style>
</head>
<body>
<h1>마우스 관련 이벤트</h1>
<form name="form1">
<textarea name="txt1"></textarea>
<input type="button" value="확인" name="btn1">
</form>
<script>
function message(txt) {
var now = new Date();
txt1.value = txt + '-' + now.toLocaleTimeString() + '\r\n' + txt1.value;
}
var txt1 = window.document.form1.txt1;
var btn1 = window.document.form1.btn1;
//onclick > 마우스 이벤트 x
btn1.onclick = m6;
function m6() {
//onclick 내에서는 마우스에 대한 정보를 알 수 없다.
message('onclick' + event.buttons);
}
</script>
</body>
</html>
// 키 관련 이벤트
- onkeyXXX
- 포커스를 가지는 태그에서만 발생(텍스트 박스, 체크 박스 등)
> 이미지 등의 태그에서 사용하려면 window에 걸어야 한다. > 전역 이벤트(화면의 모든 곳에서 발생)
- 발생 순서: keydown > keypress > keyup
1. onkeydown
- 키를 눌렀을 때 발생
- 문자에 반응하는 이벤트 X / 물리키에 반응하는 이벤트 O
- 물리키에 반응하는 이벤트 > 어떤 키를 눌렀는지가 중요하다.
- 키보드에 존재하는 모든 키에 반응한다.★★★★★★
2. onkeyup
- 키를 뗐을 때 발생
3. onkeypress
- 키를 눌렀을 때 발생
- 문자에 반응하는 이벤트 O / 물리키에 반응하는 이벤트 X
- 문자가 아닌 키에는 반응하지 않는다.★★★★★★
- 잘 사용하지 않는다.
~ event.keyCode: 입력값 코드
- 좌(37), 상(38), 우(39), 하(40)
- onkeydown / onkeyup / onkeypress
<!DOCTYPE html>
<html lang="en">
<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>
input, textarea {
display: block;
margin-bottom: 10px;
outline: none;
}
</style>
</head>
<body>
<h1>키 이벤트</h1>
<form name="form1">
<input type="text" name="txt1">
<input type="text" name="txt2">
<textarea name="txt3"></textarea>
</form>
<script>
var txt1 = window.document.form1.txt1;
var txt2 = window.document.form1.txt2;
var txt3 = window.document.form1.txt3;
txt1.onkeydown = m1;
txt1.onkeyup = m2;
txt1.onkeypress = m3;
function m1(evt) {
console.log('keydown');
}
function m2() {
console.log('keyup');
}
function m3() {
console.log('keypress');
}
</script>
</body>
</html>
- evt.keyCode
<!DOCTYPE html>
<html lang="en">
<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>
input, textarea {
display: block;
margin-bottom: 10px;
outline: none;
}
</style>
</head>
<body>
<h1>키 이벤트</h1>
<form name="form1">
<input type="text" name="txt1">
<input type="text" name="txt2">
<textarea name="txt3"></textarea>
</form>
<script>
var txt1 = window.document.form1.txt1;
var txt2 = window.document.form1.txt2;
var txt3 = window.document.form1.txt3;
txt3.onkeydown = m1;
txt3.onkeyup = m2;
txt3.onkeypress = m3;
function m1(evt) {
console.log(evt.keyCode);
if (evt.keyCode == 37) {
txt3.cols--;
} else if (evt.keyCode == 39) {
txt3.cols++;
} else if (evt.keyCode == 38) {
txt3.rows++;
} else if (evt.keyCode == 40) {
txt3.rows--;
}
}
function m2() {
// console.log('keyup');
// console.log(event.keyCode);
}
function m3() {
// console.log('keypress');
// console.log(event.keyCode);
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<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>
.item {
border: 1px solid #CCC;
background-color: #EEE;
padding: 10px;
margin: 15px;
width: 400px;
text-align: center;
}
.item > input[type=button] {
border: 1px solid #CCC;
background-color: #FFF;
width: 100px;
height: 60px;
margin: 10px;
outline: none;
}
</style>
</head>
<body>
<h1>다량의 요소(태그)의 이벤트 처리</h1>
<div class="item">
<input type="button" name="btnRed" value="빨강" onclick="m1();">
<input type="button" name="btnYellow" value="노랑" onclick="m2();">
<input type="button" name="btnBlue" value="파랑" onclick="m3();">
</div>
<div class="item">
<input type="button" name="btnRed2" value="빨강">
<input type="button" name="btnYellow2" value="노랑">
<input type="button" name="btnBlue2" value="파랑">
</div>
<div class="item">
<input type="button" value="빨강" onclick="m7('tomato');">
<input type="button" value="노랑" onclick="m7('gold');">
<input type="button" value="파랑" onclick="m7('cornflowerblue');">
</div>
<div class="item">
<input type="button" value="빨강" onclick="m8(this);">
<input type="button" value="노랑" onclick="m8(this);">
<input type="button" value="파랑" onclick="m8(this);">
</div>
<div class="item">
<input type="button" name="btnTomato" value="빨강" onclick="m9(this);">
<input type="button" name="btnGold" value="노랑" onclick="m9(this);">
<input type="button" name="btnCornflowerblue" value="파랑" onclick="m9(this);">
</div>
<div class="item">
<input type="button" name="btnRed" value="빨강" onclick="m10(this);" data-color="tomato">
<input type="button" name="btnYellow" value="노랑" onclick="m10(this);" data-color="gold">
<input type="button" name="btnBlue" value="파랑" onclick="m10(this);" data-color="cornflowerblue">
</div>
<div class="item">
<input type="button" name="btnRed" value="빨강" onclick="m11();" data-color="tomato">
<input type="button" name="btnYellow" value="노랑" onclick="m11();" data-color="gold">
<input type="button" name="btnBlue" value="파랑" onclick="m11();" data-color="cornflowerblue">
</div>
<div class="item">
<input type="button" name="btnRed3" value="빨강" data-color="tomato">
<input type="button" name="btnYellow3" value="노랑" data-color="gold">
<input type="button" name="btnBlue3" value="파랑" data-color="cornflowerblue">
</div>
<div class="item">
<input type="button" name="btn" value="빨강" data-color="tomato">
<input type="button" name="btn" value="노랑" data-color="gold">
<input type="button" name="btn" value="파랑" data-color="cornflowerblue">
</div>
<hr>
<script>
function m1() {
document.body.bgColor = 'tomato';
}
function m2() {
document.body.bgColor = 'gold';
}
function m3() {
document.body.bgColor = 'cornflowerblue';
}
document.all.btnRed2.onclick = m4;
document.all.btnYellow2.onclick = m5;
document.all.btnBlue2.onclick = m6;
function m4() {
document.body.bgColor = 'tomato';
}
function m5() {
document.body.bgColor = 'gold';
}
function m6() {
document.body.bgColor = 'cornflowerblue';
}
function m7(color) {
document.body.bgColor = color;
}
//함수 내의 this는 window 객체를 말한다.
function m8(btn) {
// alert(btn.value);
// alert(this.value)
if (btn.value == '빨강') {
document.body.bgColor = 'tomato';
} else if(btn.value == '노랑') {
document.body.bgColor = 'gold';
} else if(btn.value == '파랑'){
document.body.bgColor = 'cornflowerblue';
}
}
function m9(btn) {
document.body.bgColor = btn.name.substring(3);
}
function m10(btn) {
// alert(btn.dataset['color']);
document.body.bgColor = btn.dataset['color']
}
function m11() {
//어떤 버튼이 눌렸는지?
//- event 객체 > 눌린 버튼 프로퍼티 제공
// alert(event.srcElement)
// alert(event.target)
// alert(event.target.dataset['color']);
document.body.bgColor = event.target.dataset['color'];
}
document.all.btnRed3.onclick = m12;
document.all.btnYellow3.onclick = m12;
document.all.btnBlue3.onclick = m12;
function m12() {
document.body.bgColor = event.target.dataset['color'];
}
//name='btn' 배열
//1. name 유일 > 단일 객체
//2. name 중복 > 배열
// alert(document.all.btn.length);
for(var i = 0; i < document.all.btn.length; i++) {
document.all.btn[i].onclick = m13;
}
function m13() {
document.body.bgColor = event.target.dataset['color'];
}
</script>
</body>
</html>
// DOM 이벤트
~ addEventListener(원하는조작, 함수) > 이벤트 설정
~ removeEventListener(원하는조작, 함수) > 이벤트 제거
- 이벤트 매핑을 관리할 수 있다.
> Invocation List(이벤트 함수 목록)
- addEventListener
<!DOCTYPE html>
<html lang="en">
<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>
</style>
</head>
<body>
<h1>DOM Event</h1>
<input type="button" value="BOM" id="btn1" name="btn1">
<input type="button" value="DOM" id="btn2" name="btn2">
<script>
const btn1 = document.getElementById('btn1');
const btn2 = document.getElementById('btn2');
//이벤트 매핑을 관리할 수 있다.
btn2.addEventListener('click', m1);
btn2.addEventListener('click', m2); //누적
function m1() {
alert('m1');
}
function m2() {
alert('m2');
}
</script>
</body>
</html>
- removeEventListener
<!DOCTYPE html>
<html lang="en">
<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>
</style>
</head>
<body>
<h1>DOM Event</h1>
<input type="button" value="BOM" id="btn1" name="btn1">
<input type="button" value="DOM" id="btn2" name="btn2">
<script>
const btn1 = document.getElementById('btn1');
const btn2 = document.getElementById('btn2');
//이벤트 매핑을 관리할 수 있다.
btn2.addEventListener('click', m1);
btn2.addEventListener('click', m2); //누적
btn2.removeEventListener('click', m1)
function m1() {
alert('m1');
}
function m2() {
alert('m2');
}
</script>
</body>
</html>
// 이벤트 버블링(Event Bubbling), 이벤트 터널링(Event Tunneling, 이벤트 캡쳐링(Event Capturing))
- 이벤트는 태그 계층구조에 따라 순차적으로 전달 및 실행된다.
~ 이벤트 터널링: 상위 계층부터 하위 계층까지 순차적으로 이벤트를 전달한다.
~ 이벤트 버블링: 하위 계층부터 상위 계층까지 순차적으로 이벤트를 수행한다.
- 자바스크립트는 기본적으로 이벤트만 발생한다.(원하면 이벤트 터널링도 발생시킬 수는 있다. > DOM으로만 가능)
> 내려가다가 이벤트가 걸린 곳에서 유턴한다.
- event.target★★ , event.srcElement: 유턴하는 객체
- this, event.currentTarget★★: 이벤트를 소유하는 객체
- addEventListener(원하는조작, 함수, true): 이벤트 터널링 구현
- 이벤트 버블링 중단(이벤트 발생 사실을 상위 계층에 알리지 않는다.)
1. event.cancelBubble = true; > 비표준(MS) > IE 전용
2. event.stopPropagation(); > 표준 > 권장
- BOM
<!DOCTYPE html>
<html lang="en">
<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>
.box { padding: 50px; }
#p1 { background-color: tomato;}
#p2 { background-color: gold;}
#p3 { background-color: cornflowerblue;}
</style>
</head>
<body>
<div id="p1" class="box">
<div id="p2" class="box">
<div id="p3" class="box"></div>
</div>
</div>
<script>
const p1 = document.getElementById('p1')
const p2 = document.getElementById('p2')
const p3 = document.getElementById('p3')
//이벤트 버블링(Event Bubbling)
// vs 이벤트 터널링(Event Tunneling, 이벤트 캡쳐링(Event Capturing))
p1.onclick = function () {
alert('빨강' + event.target.id);
};
p2.onclick = function() {
// alert('노랑' + event.target.id + event.srcElement.id + this.id + event.currentTarget.id);
alert('노랑' + event.target.id);
};
p3.onclick = function() {
alert('파랑' + event.target.id);
event.cancelBubble = true;
};
</script>
</body>
</html>
- DOM( 이벤트 터널링)
<!DOCTYPE html>
<html lang="en">
<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>
.box { padding: 50px; }
#p1 { background-color: tomato;}
#p2 { background-color: gold;}
#p3 { background-color: cornflowerblue;}
</style>
</head>
<body>
<div id="p1" class="box">
<div id="p2" class="box">
<div id="p3" class="box"></div>
</div>
</div>
<script>
const p1 = document.getElementById('p1')
const p2 = document.getElementById('p2')
const p3 = document.getElementById('p3')
//DOM
//이벤트 터널링
p1.addEventListener('click', function() {
alert('빨강');
}, true);
p2.addEventListener('click', function() {
alert('노랑');
}, true);
p3.addEventListener('click', function() {
alert('파랑');
}, true);
//이벤트 버블링
p1.addEventListener('click', function() {
alert('빨강');
});
p2.addEventListener('click', function() {
alert('노랑');
});
p3.addEventListener('click', function() {
alert('파랑');
});
</script>
</body>
</html>
'클라이언트 > JavaScript' 카테고리의 다른 글
[자바스크립트(JavaScript)] BOM(Window, Screen, Location, History) (0) | 2023.04.24 |
---|---|
HTML 속성 제어(태그 조작) (0) | 2023.04.21 |
[자바스크립트(JavaScript)] 상속 (0) | 2023.04.09 |
[자바스크립트(JavaScript)] 파일 쪼개기 (0) | 2023.03.22 |
[자바스크립트(JavaScript)] 객체 (0) | 2023.03.19 |