1. 노드의 속성 추가 및 제거
- getAttribute(): 요소의 속성 취득
- setAttribute(): 요소의 속성 저장
- removeAttribute(): 요소의 속성 제거
2. 이벤트 객체(정말 중요함)
- 이벤트 발생시 실행되는 함수의 (인자값) 으로 현재 실행되는 event객체를 넣어주게 되어 있다.
- stopPropagation(): 이벤트 전파를 막는다. (버블링 중단하기)
- target: 이벤트를 적용한 타겟 속성
- currentTarget: 실제 이벤트가 걸려있는 타겟 속성
- preventDefault(): 고유특성을 가진 태그의 이벤트를 제거
* 예제(다중 이벤트, 이벤트 전파)
<!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>
<script>
var result = document.querySelector(".result");
var item = document.querySelectorAll(".item");
//console.log(item); //아이템은 배열
//이 방법은 비효율적인 방법입니다. - 태그 10000개라면? 좋은 코드가 아닙니다.
for(var i = 0; i < item.length; i++){
item[i].onclick = function(e){
result.innerHTML = this.innerHTML;
}
}
</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>
</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); //ul
// result.innerHTML = this.innerHTML; //ul
// console.log("이벤트 동작"); //누를 때마다 console창에 이벤트 동작이라고 뜸
// 이벤트 객체 - 이벤트 함수에 첫번째 매개변수로 자동전달 됩니다.
// console.log(a);
// console.log(event);
// console.log(e);
// console.log(event.target); //이벤트가 동작된 실제 태그
// console.log(event.currentTarget); //이벤트가 실제 걸려있는 위치(태그)
console.dir(e.target);
console.dir(li);
if(e.target.tagName != "LI") return; //li 태그가 아니라면 종료
result.innerHTML = e.target.innerHTML; //e.target = li
}
</script>
</body>
</html>
* 실습 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>
<style>
ul li {
display: inline-block;
}
</style>
<h3>이벤트객체활용</h3>
<div>
<ul class="parent">
<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");
var parent = document.querySelector(".parent");
//부모 태그가 이벤트를 가지면 자식 태그 전부 다 동일한 이벤트를 가지기 때문에 All보다 selector로 사용하는게 좋음
//querySelectorAll을 사용할 때
// parent[0].onclick = function (e) {
// console.log(result.src);
// result.src = e.target.src;
// }
parent[0].onclick = function (e) {
console.log(result.src);
result.src = e.target.src;
}
</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>
</head>
<body>
<style>
ul li {
display: inline-block;
}
</style>
<h3>이벤트객체활용</h3>
<div>
<ul class="box">
<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");
var box = document.querySelector(".box");
box.onclick = function () {
if(event.target.tagName != "IMG") return;
result.src = event.target.src;
}
</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>
<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">삭제</button></td>
</tr>
<tr>
<td>2</td>
<td>첫글</td>
<td>hi</td>
<td><button type="button">삭제</button></td>
</tr>
<tr>
<td>3</td>
<td>첫글</td>
<td>hi</td>
<td><button type="button">삭제</button></td>
</tr>
<tr>
<td>4</td>
<td>첫글</td>
<td>hi</td>
<td><button type="button">삭제</button></td>
</tr>
</tbody>
<script>
var list = document.querySelector(".list");
list.onclick = function (e) {
if (event.target.tagName != "BUTTON") return;
//타겟이 발생한 곳의 tr을 지워야하니까 button에서 td tr 이렇게 올라가서 부모의 부모로 해줘야함.
e.target.parentElement.parentElement.remove();
}
</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>
.func1 {width: 300px; height: 300px; background-color: red;}
.func2 {width: 200px; height: 200px; background-color: blue;}
.func3 {width: 100px; height: 100px; background-color: yellow;}
</style>
</head>
<body>
<div class ="func1">
<div class = "func2">
<div class = "func3">func3 자식</div>
</div>
</div>
<script>
/*
dom에서 이벤트 동작 방식은 기본으로 버블링입니다.
버블링 - 부모, 자식 모두에 이벤트가 있을 때 이벤트가 자식 → 부모 방향으로 전파되는 특징
func3누르면 func3-func2-func1 실행
*/
// var func1 = document.querySelector(".func1");
// func1.onclick = function(){
// alert("func1");
// }
// var func2 = document.querySelector(".func2");
// func2.onclick = function(){
// event.stopPropagation(); //이벤트 버블링 중단(웬만하면 안씀)
// alert("func2");
// }
// var func3 = document.querySelector(".func3");
// func3.onclick = function(){
// alert("func3");
// }
/*
이벤트 캡쳐링 → 부모, 자식에 이벤트가 있을 때, 부모에서 자식으로 전파되는 특징
addEventListener() 방식으로만 구현해 줄 수 있습니다.
3번을 눌렀더니 1 2 3 순서로 실행됨.
*/
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() {
event.stopPropagation(); //이벤트 캡쳐링 중단(3번 누르니까 본인꺼 실행이 안됨)
alert("func2");
}, true);
func3.addEventListener("click", function() {
alert("func3");
}, true);
</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>
</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);
console.log(event.target.classList);
var arr = event.target.classList;
if(arr.contains("sel")) { //선택 버튼 (add, contains, remove) 사용 가능
event.target.previousElementSibling.style.color = "red";
} else if (arr.contains("del")) { //삭제 버튼
event.target.parentElement.remove();
} else if(arr.contains("aaa")){ //aaa 버튼
}
}
</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>
</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; //tagName은 개발자 도구 켜서 확인이 가능합니다.
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의 고유 이벤트 중단
console.dir(event);
}
</script>
</body>
</html>
* 예제(이벤트 객체와 dataset)
<!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 속성 - tag의 저장소</h3>
<!-- data-로 시작하고, 뒤에 오는 이름은 자유롭게 작성-->
<ul class = "list">
<li><a href = "#" data-user-info='{"id": "1", "age": "10"}' data-reference>홍길동</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": "40"}'>박찬호</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); //err
console.log(result);
}
</script>
</body>
</html>