728x90
이벤트 객체
- 모든 이벤트에서 이벤트 객체 사용 가능 (꼭 다중 이벤트 상황이 아니어도 가능)
< 약속 > 이벤트 발생시 실행되는 함수의 (인자값, 첫번째 매개변수)로 현재 실행되는 event 객체를 넣어줌
이벤트 객체의 기능 | ||
stopPropagation() | 이벤트 전파를 막음 (버블링 중단하기) | 굳이 사용x |
target | 이벤트를 적용한 타겟 속성 | 클릭한 대상, 선택한 것 |
currentTarget | 실제 이벤트가 걸려있는 타겟 속성 | 부모의 위치 |
preventDefault() | 태그의 고유 이벤트 제거 | a, submit 태그 같은 경우 모달창 띄우고 싶을 때 새로운 페이지로 안 넘어가게끔 |
이벤트 전파 (a.k.a 상속)
- 부모에 하나의 이벤트만 걸어 놓으면, 모든 이벤트가 동일하게 자식으로 위임
- li에 일일히 이벤트를 등록하는 작업을 없앨 수 있음
이벤트 위임
- 부모에 이벤트를 걸어 두면 자식이 동일한 이벤트를 위임받음
- li에 일일히 이벤트를 등록하는 작업을 없앨 수 있음
이벤트 실행방식
1. 캡쳐링 ▶ 2. target ▶ 3. 버블링
누르면 올라가면서(버블링 하면서) 부모 이벤트를 실행시켜 주고 감
기본적으로 선언하는 이벤트 함수는 버블링으로 실행
둘 다 실행하면 2번 하니까 캡쳐링에서는 X
이벤트 버블링
- DOM의 이벤트 동작 방식
- 부모, 자식 모두 이벤트가 걸려있을 때, 자식 ▶ 부모 실행
이벤트 캡쳐링
- 부모, 자식 모두 이벤트가 걸려있을 때, 부모 ▶ 자식 실행
addEventListener()로만 구현 가능 (구현할 일 X)
클릭을하면 window객체에서 탐색을 하면서 어디서 발생했는지 알아봄 - capturing
타겟이 확인되면 어디에서 일어났는지 window에게 알려주기 위해 올라감 - bubbling
실습
더보기
1. 여러 이벤트를 한번에 걸어주기 - 반복문 사용 (비효율적)
<!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>
</head>
<body>
<h3>여러 이벤트를 한번에 걸어주기</h3>
<ul>
<li class="item">1.일인자</li>
<li class="item">2.이인자</li>
<li class="item">3.삼인자</li>
<li class="item">4.사인자</li>
<li class="item">5.오인자</li>
</ul>
선택한 태그의 값:
<p class="result"></p>
<!-- all로 li를 다 얻어서 반복문으로 하나씩 이벤틀 걸어주면 됨 -->
<script>
var result = document.querySelector(".result");
var item = document.querySelectorAll(".item"); //li 전부 얻어오기, 배열임
//이 방법은 비효율적인 방법 - 태그 100000개 이상이라면 ~??, 좋은 코드가 아님
for(var i = 0; i < item.length; i++) {
item[i].onclick = function() { //item의 i번째를 클릭하면~
result.innerHTML = this.innerHTML; //this 현재 클릭한 li의 innerHTML을 result.innerHTML에 넣어줌
}
}
</script>
</body>
</html>
2. 이벤트 전파 특성 활용하기
<!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>
</head>
<body>
<h3>이벤트 전파 특성 활용하기</h3>
<ul class="parent">
<li>1.일인자</li>
<li>2.이인자</li>
<li>3.삼인자</li>
<li>4.사인자</li>
<li>5.오인자</li>
</ul>
선택한 태그의 값:
<p class="result"></p>
<script>
var result = document.querySelector(".result");
//부모에 이벤트를 걸면 자식한테 이벤트가 전파됨
var parent = document.querySelector(".parent"); //ul
parent.onclick = function(e) {
// console.log(this); //this는 ul
// result.innerHTML = this.innerHTML; //1~5까지 한번에 다 들어옴
// 이벤트 객체 - 이벤트 함수에 첫번째 매개변수로 자동 전달 됨
// console.log(e); //1. 매개변수로 받거나
// console.log(event); //2. 직접 event 객체를 넣거나
// console.log(event.target); //이벤트가 동작된 실제 태그
// console.log(event.currentTarget); //실제 이벤트가 걸려있는 태그
// e.target //li태그
// console.dir(e.target); //tagName 확인방법
if(e.target.tagName != "LI") return; //li태그가 아니라면 종료
result.innerHTML = e.target.innerHTML;
}
</script>
</body>
</html>
3. 이벤트 객체 활용
<!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>
ul li {
display: inline-block;
}
</style>
</head>
<body>
<h3>이벤트객체활용</h3>
<div>
<ul class="parent"> <!-- 부모 태그에 class -->
<li><img src="img/1.jpg" alt="1" width="100"></li>
<li><img src="img/2.jpg" alt="1" width="100"></li>
<li><img src="img/3.jpg" alt="1" width="100"></li>
<li><img src="img/4.jpg" alt="1" width="100"></li>
</ul>
결과:
<div class="result">
<img src="img/1.jpg" alt="결과" width="300" >
</div>
</div>
<script>
var result = document.querySelector(".result > img"); //result-img의 scr속성을 변경해야 하기 때문에
var parent = document.querySelector(".parent");
parent.onclick = function() {
// console.log(event.target); //클릭한 li값, 현재 result값
// console.dir(event.target); //tagName 확인방법
if(event.target.tagName != "IMG") return; //li태그가 아니라면 종료
result.src = event.target.src; //클릭한 li의 scr를 result.src에 넣어줌
}
</script>
</body>
</html>
4. 이벤트 위임 이용
<!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>
ul li {
display: inline-block;
}
table { border-collapse: collapse; border-spacing : 0;}
thead th, tbody td {
border: 1px solid black;
}
</style>
</head>
<body>
<h2>이벤트 위임 이용해서 다음을 만들어 보세요.<h2>
<table>
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>내용</th>
<th>삭제</th>
</tr>
</thead>
<tbody class="list">
<tr>
<td>1</td>
<td>첫글</td>
<td>hi</td>
<td><button type="button" class="btn">삭제</button></td>
</tr>
<tr>
<td>2</td>
<td>첫글</td>
<td>hi</td>
<td><button type="button" class="btn">삭제</button></td>
</tr>
<tr>
<td>3</td>
<td>첫글</td>
<td>hi</td>
<td><button type="button" class="btn">삭제</button></td>
</tr>
<tr>
<td>4</td>
<td>첫글</td>
<td>hi</td>
<td><button type="button" class="btn">삭제</button></td>
</tr>
</tbody>
</table>
<script>
//삭제 버튼의 공통적인 부모인 tbody에 동작을 걸어야 함 (tr은 삭제버튼마다 다름)
var list = document.querySelector(".list"); //tbody 부모 클래스 가져옴, 표 다 가져오기
list.onclick = function() {
console.log(event.target); //누른 button임
if(event.target.tagName != "BUTTON") return; //버튼일때만 동작
event.target.parentElement.parentElement.remove(); //tr삭제
}
</script>
</body>
</html>
5.
<!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>
.func1 {width: 300px; height: 300px; background-color: rgb(255, 58, 58);}
.func2 {width: 200px; height: 200px; background-color: rgb(77, 88, 247);}
.func3 {width: 100px; height: 100px; background-color: chartreuse;}
</style>
</head>
<body>
<div class="func1">
<div class="func2">
<div class="func3"> func3자식 </div>
</div>
</div>
<script>
/*
DOM에서 이벤트 동작방식은 기본으로 버블링 입니다.
버블링 - 부모, 자식 모두에 이벤트가 있을 때 이벤트가 자식 → 부모 방향으로 전파되는 특징
3번 클릭 - 3 ▶ 2 ▶ 1로 실행
*/
// var func1 = document.querySelector(".func1");
// func1.onclick = function() {
// alert("func1");
// }
// var func2 = document.querySelector(".func2");
// func2.onclick = function() {
// // event.stopPropagation(); //이벤트 버블링 중단, 3번 누르면 3 ▶ 2 실행, 거의 안씀
// alert("func2");
// }
// var func3 = document.querySelector(".func3");
// func3.onclick = function() {
// alert("func3");
// }
/*
이벤트 캡쳐링 - 부모, 자삭에 이벤트가 있을 때, 부모 ▶ 자식으로 전파되는 특징
addEventListener() 방식으로만 구현해 줄 수 있습니다.
*/
var func1 = document.querySelector(".func1");
var func2 = document.querySelector(".func2");
var func3 = document.querySelector(".func3");
func1.addEventListener("click", function() {
alert("func1");
}, true);
func2.addEventListener("click", function() {
alert("func2");
}, true);
func3.addEventLis3ener("click", function() {
alert("func1");
}, true);
/* 이 방식으로 하면 fun3을 클릭해도 func1 ▶ 2 ▶ 3 순서로 진행 */
</script>
</body>
</html>
6.
<!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>
</head>
<body>
<section id="section">
<div class="list">
<div>
<span>홍길동</span>
<button type="button" class="btn sel">선택</button>
<button type="button" class="btn del">삭제</button>
<button type="button" class="btn aaa">aaa</button>
</div>
<div>
<span>김길동</span>
<button type="button" class="btn sel">선택</button>
<button type="button" class="btn del">삭제</button>
<button type="button" class="btn aaa">aaa</button>
</div>
<div>
<span>홍길자</span>
<button type="button" class="btn sel">선택</button>
<button type="button" class="btn del">삭제</button>
<button type="button" class="btn aaa">aaa</button>
</div>
</div>
</section>
<script>
var list = document.querySelector(".list");
list.onclick = function () {
if(event.target.tagName != "BUTTON") return; //버튼이 아니라면 종료
// console.log(event.target.className); //버튼의 className
// console.log(event.target.classList); //버튼의 class 이름 list
var arr = event.target.classList;
// 각각의 버튼의 동작이 다르기 때문에 class 속성 이용
if(arr.contains("sel")) {//선택버튼
event.target.previousElementSibling.style.color = "blue";
} else if(arr.contains("del")) { //삭제버튼
event.target.parentElement.remove();
} else if(arr.contains("aaa")) { //aaa버튼
}
}
</script>
</body>
</html>
7.
<!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>
</head>
<body>
<div>
<ul class="page">
<li><a href="list.board">1</a></li>
<li><a href="list.board">2</a></li>
<li><a href="list.board">3</a></li>
<li><a href="list.board">4</a></li>
<li><a href="list.board">5</a></li>
</ul>
</div>
<script>
var page = document.querySelector(".page");
page.onclick = function() {
event.preventDefault(); //a태그 or submit이 가진 기본이벤트를 중단
if(event.target.tagName != "A") return; //A가 아니라면 종료
console.log(event.target.innerHTML);
}
</script>
<hr>
<form action="https://www.naver.com">
<input type="text" name="age">
<input type="submit" value="클릭" id="btn">
</form>
<script>
var btn = document.getElementById("btn");
btn.onclick = function () {
event.preventDefault(); //submit의 고유이벤트 중단
//처리하면 됨
}
</script>
</body>
</html>
data - (하이픈) ▶ 교안 x
- 어떤 값이던지 json으로 저장 가능
- 태그의 dataset 속성 - 태그의 저장소
- data - 으로 시작하고, 뒤에 오는 이름은 자유롭게 작성
- 태그에 값을 저장할 수 있는 저장소 - 태그 안의 값을 찾아 쓰기 위해
data - 이름 마음대로 = "문자열"
data - 이름 마음대로 = '{ id: 1, age:20 }' //필요한 정보 저장 가능
실습
<!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>
</head>
<body>
<h3>태그의 dataset 속성 - 태그의 저장소</h3>
<ul class="list">
<li><a href="#" data-user-info='{"id": "1", "age":"10"}'>홍길동</a></li>
<li><a href="#" data-user-info='{"id": "2", "age":"20"}'>홍길자</a></li>
<li><a href="#" data-user-info='{"id": "3", "age":"30"}'>이순신</a></li>
<li><a href="#" data-user-info='{"id": "4", "age":"4"}'>박찬호</a></li>
</ul>
결과: <div class="result"></div>
<script>
var list = document.querySelector(".list");
list.onclick = function() {
//1.
event.preventDefault();
//2.
if(event.target.tagName != "A") return;
//3. data - 으로 만들어진 속성은 태그에서 찾아 쓸 수 있어요~
// console.dir(event.target);
// console.dir(event.target.dataset);
// console.dir(event.target.dataset.userInfo);
var data = event.target.dataset.userInfo;
var result = JSON.parse(data); //key, value값 ""로 묶어야 에러 안남
console.log(result);
}
</script>
</body>
</html>
- 메뉴1
- 메뉴2
- 메뉴3
<!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>
.toggle li {
display: inline-block;
padding: 15px 20px 14px;
width: 25%;
text-align: center;
border: 1px solid #333;
cursor: pointer;
}
.toggle-menu {display: none;}
.active { display: block; animation: fadeIn 1s ease-in-out;} /* active가 옮겨지면서 내용이 보여지고, 안보여짐 */
/* 애니메이션 라이브러리 사이트: https://michalsnik.github.io/aos/, https://whirl.netlify.app/ */
/* 애니메이션 */
@keyframes fadeIn {
from { /* from에서 to로 바꾸겠다 */
opacity: 0;
background-color: aquamarine;
margin-left: -100px;
} to {
opacity: 1;
background-color: beige;
margin-left: 0;
}
}
</style>
</head>
<body>
<!--
1. ul에 이벤트 버블링을 이용해서 클릭이벤트를 걸고 클릭되는 타겟의 data-id를 얻습니다.
2. toggle-menu의 active속성을 삭제
3. data-id의 값에 알맞는 태그에 active속성을 추가하면됩니다.
-->
<section>
<ul class="toggle">
<li data-id="#toggle1">메뉴1</li>
<li data-id="#toggle2">메뉴2</li>
<li data-id="#toggle3">메뉴3</li>
</ul>
<div class="menu">
<div class="toggle-menu active" id="toggle1">
토글메뉴1
</div>
<div class="toggle-menu" id="toggle2">
토글메뉴2
</div>
<div class="toggle-menu" id="toggle3">
토글메뉴3
</div>
</div>
</section>
<script>
var toggle = document.querySelector(".toggle"); //ul 가져옴, 부모태그 가져옴
var menu = document.querySelector(".menu"); //토글메뉴 3개 다 나옴
toggle.onclick = function() {
var active = document.querySelector(".active");
var click = document.querySelector(event.target.dataset.id); //누른 버튼의 id가져와서 변수에 담음
// console.log(event.target); //target은 각각의 li임
// console.log(event.target.dataset.id); //각각의 data-id 나옴
if(event.target.tagName != "LI") return; //li일때만 동작하게끔
console.log(active);
active.classList.remove("active");
console.log(click);
click.classList.add("active");
//if 아래 다른 풀이
var trigger = event.target.dataset.id;
var tag = document.querySelector(trigger); //id를 가지고 있는 태그
//다른 태그는 active 삭제, 반복문으로 돌려서 삭제
var menu = document.querySelectorAll(".toggle-menu");
for(var i = 0; i < menu.length; i++) {
menu[i].classList.remove("active");
}
tag.classList.add("active"); //active 추가
}
</script>
</body>
</html>
애니메이션 추가
@keyframes
애니메이션 사용방법
<style>
.active { display: block; animation: fadeIn 1s ease-in-out;} /* active가 옮겨지면서 내용이 보여지고, 안보여짐 */
/* 애니메이션 */
@keyframes fadeIn {
from { /* from에서 to로 바꾸겠다 */
opacity: 0;
background-color: aquamarine;
margin-left: -100px;
} to {
opacity: 1;
background-color: beige;
margin-left: 0;
}
}
</style>
fadeIn
애니메이션 라이브러리 사이트
오늘 하루
더보기
기억에 남는 부분
-
-
어려운 부분
-
-
문제 해결 부분
-
-
728x90
'클라이언트 > JavaScript' 카테고리의 다른 글
[JavaScript] BOM - window, location, history, navigator, document callback, cookie&session (0) | 2023.01.04 |
---|---|
[JavaScript] form객체, 정규분포표, date객체 (0) | 2023.01.04 |
[JavaScript] node remove, select(parent,children), class 속성제어 (1) | 2023.01.02 |
[JavaScript] node select, create, onfocus&onblur (0) | 2022.12.30 |
[JavaScript] 이벤트 핸들러, this, BOM, DOM (0) | 2022.12.29 |