23-01-02 부모 노드,자식 노드 선택, 노드 삭제, 노드 삽입(insertBefore(삽입노드,기준노드);) , 클래스 속성 제어하기
#나중에도 또 사용하기 때문에 잘 기억해두기.
* 아래를 보면 공백을 우리가 다룰 일은 없기 때문에 Element가 붙은 애들위주로 사용해주면 된다.
Element가 붙은 친구들은 순수한 태그의 형태만 선택해준다.
- 아래와 같이 dir 을 이용해서 x 라는 태그를 찍어주면
x라는 태그에 어떤 속성들을 사용할 수 있는지 목록이 쭉 나온다. ( 태그를 갖고 어떤 태그들을 적용할 수 있을지 기억이 안날 때 사용하자.)

*부모,자식 노드 선택
-코드
<body>
<table >
<thead>
<tr>
<th>이동</th>
<th>번호</th>
<th>이름</th>
<th>내용</th>
<th>날짜</th>
</tr>
</thead>
<tbody class="table">
<tr>
<td><button onclick="down(this)">↓</button><button onclick="">↑</button></td>
<td>1</td>
<td>홍길자</td>
<td>안녕!</td>
<td>2019-01-01</td>
</tr>
<tr>
<td><button onclick="down(this)">↓</button><button onclick="">↑</button></td>
<td>2</td>
<td>이순신</td>
<td>반가워</td>
<td>2019-02-01</td>
</tr>
<tr>
<td><button onclick="down(this)">↓</button><button onclick="">↑</button></td>
<td>3</td>
<td>이순신</td>
<td>반가워</td>
<td>2019-02-01</td>
</tr>
<tr>
<td><button onclick="down(this)">↓</button><button onclick="">↑</button></td>
<td>4</td>
<td>이순신</td>
<td>반가워</td>
<td>2019-02-01</td>
</tr>
<tr>
<td><button onclick="down(this)">↓</button><button onclick="">↑</button></td>
<td>5</td>
<td>이순신</td>
<td>반가워</td>
<td>2019-02-01</td>
</tr>
</tbody>
</table>
<script>
function down(x){
//console.log(x);//자신태그
//console.dir(x);// 태그에 사용할 수 있는 속성이 무엇이 있는지 모두 출력해줌.
//console.log(x.parentNode);//부모태그(공백이 있다면, 공백을 선택)
//console.log(x.parentElement);//부모태그(순수한 태그의 형태만 선택)
//console.log(x.parentElement.nextElementSibling);//다음형제
//console.log(x.parentElement.nextElementSibling.nextElementSibling);
//console.log(x.previousElementSibling); //이전형제(현재없음)
//console.log(x.parentElement.parentElement.firstElementChild);//tr기준 첫번째 자식태그
//console.log(x.parentElement.parentElement.lastElementChild);//tr기준 마지막번째 자식태그
console.log(x.parentElement.parentElement.children[2]);//자식들중 3번째
}
</script>
</body>
-출력창
*insertBefore(삽입노드, 기준노드)
- 기준 노드를 설정하고, 그 바로 전 자리에 노드를 삽입해주는 메소드.
- insertBefore을 사용할 땐 자리롤 옮겨주고자 하는 태그들의 부모 태그에다가 .을 찍고 사용해주면 된다.
-코드
<body>
<table >
<thead>
<tr>
<th>이동</th>
<th>번호</th>
<th>이름</th>
<th>내용</th>
<th>날짜</th>
</tr>
</thead>
<tbody class="table">
<tr>
<td><button onclick="down(this)">↓</button><button onclick="">↑</button></td>
<td>1</td>
<td>홍길자</td>
<td>안녕!</td>
<td>2019-01-01</td>
</tr>
<tr>
<td><button onclick="down(this)">↓</button><button onclick="">↑</button></td>
<td>2</td>
<td>이순신</td>
<td>반가워</td>
<td>2019-02-01</td>
</tr>
<tr>
<td><button onclick="down(this)">↓</button><button onclick="">↑</button></td>
<td>3</td>
<td>이순신</td>
<td>반가워</td>
<td>2019-02-01</td>
</tr>
<tr>
<td><button onclick="down(this)">↓</button><button onclick="">↑</button></td>
<td>4</td>
<td>이순신</td>
<td>반가워</td>
<td>2019-02-01</td>
</tr>
<tr>
<td><button onclick="down(this)">↓</button><button onclick="">↑</button></td>
<td>5</td>
<td>이순신</td>
<td>반가워</td>
<td>2019-02-01</td>
</tr>
</tbody>
</table>
<script>
function down(x){
//console.log(x);//자신태그
//console.dir(x);// 태그에 사용할 수 있는 속성이 무엇이 있는지 모두 출력해줌.
//console.log(x.parentNode);//부모태그(공백이 있다면, 공백을 선택)
//console.log(x.parentElement);//부모태그(순수한 태그의 형태만 선택)
//console.log(x.parentElement.nextElementSibling);//다음형제
//console.log(x.parentElement.nextElementSibling.nextElementSibling);
//console.log(x.previousElementSibling); //이전형제(현재없음)
//console.log(x.parentElement.parentElement.firstElementChild);//tr기준 첫번째 자식태그
//console.log(x.parentElement.parentElement.lastElementChild);//tr기준 마지막번째 자식태그
//console.log(x.parentElement.parentElement.children);//자식들
//console.log(x.parentElement.parentElement.children[2]);//자식들중 3번째
var current = x.parentElement.parentElement;//버튼의 부모행(tr)
var next = current.nextElementSibling;//tr의 다음행
if(next == null){
alert("마지막 행 입니다");
return;//함수종료
}
//insertBefore는 동작시킬 태그의 부모태그를 얻습니다.
var table = document.querySelector(".table");
table.insertBefore(next,current);//current앞에 next를 넣는다.
}
</script>
</body>
-결과
*remover()는 자기 자신을 날려버리는 것.
*removerChild() 는 태그의 자식노드를 삭제하는 것.
*실행예시
-코드
<!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>
table {border-spacing: 0; border-collapse: collapse;}
thead th, tbody td {
border: 1px solid black;
}
</style>
</head>
<body>
<button button="type" id="delOne">하나씩 삭제</button>
<button button="type" id="del">일괄 삭제</button>
<table>
<thead>
<th><input type="checkbox" class="allCheck"></th>
<th>번호</th>
<th>이름</th>
<th>내용</th>
<th>날짜</th>
</thead>
<tbody class="table">
<tr>
<td><input type="checkbox" class="check"></td>
<td>1</td>
<td>홍길자</td>
<td>안녕!</td>
<td>2019-01-01</td>
</tr>
<tr>
<td><input type="checkbox" class="check"></td>
<td>2</td>
<td>김길자</td>
<td>안녕!</td>
<td>2019-01-01</td>
</tr>
<tr>
<td><input type="checkbox" class="check"></td>
<td>3</td>
<td>이길자</td>
<td>안녕!</td>
<td>2019-01-01</td>
</tr>
<tr>
<td><input type="checkbox" class="check"></td>
<td>4</td>
<td>고길자</td>
<td>안녕!</td>
<td>2019-01-01</td>
</tr>
</tbody>
<script>
//하나씩 삭제 removeChild
var delOne = document.getElementById("delOne");
delOne.onclick = function(){
var table = document.querySelector(".table");//tr의 부모요소
//console.log(table.firstElementChild);//첫번째 요소
//console.log(table.children[0]);//첫번째 요소
//table.removeChild(table.firstElementChild);//첫번째 요소부터 삭제들어감
table.removeChild(table.lastElementChild);//마지막째 요소부터 삭제
}
//일괄 삭제 remove
var check = document.querySelectorAll(".check");//체크박스 전부
var del = document.getElementById("del");
del.onclick = function(){
// console.log(check[0].checked);
//console.log(confirm("삭제 할거니"));
if(confirm("정말 삭제 하시겠습니까?") == false){
return;
}
for(var i = 0; i < check.length; i++){
//console.log(check[i].checked);
if(check[i].checked){
check[i].parentElement.parentElement.remove(); //tr삭제
}
}
}
//일괄선택 vs 일괄해제
var allCheck = document.querySelector(".allCheck");
allCheck.onclick = function(){
//console.log(allCheck.checked);
if(allCheck.checked){//전부체크로 변경
for(var i = 0; i<check.length; i++){
check[i].checked = true;
}
} else {//전부체크를 해제
for(var i=0; i<check.length; i++){
check[i].checked = false;
}
}
}
</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>
<button type="button" class="delAll">전체삭제하기</button>
<div>
<h3 class="todoTitle" style="display:none;"></h3>
<input type="text" class="todoName" placeholder="이름">
<button type="button" class="todoBtn">확인</button><br>
<input type="text" class="todo" placeholder="할일">
<button type="button" class="addBtn">추가</button>
<ul class="todoList">
</ul>
</div>
<script>
var todoTitle = document.querySelector(".todoTitle");
var todoName = document.querySelector(".todoName");
var todoBtn = document.querySelector(".todoBtn");
todoBtn.onclick = function() {
todoTitle.innerHTML = todoName.value + "님 환영합니다";
todoName.style.display = "none";
todoTitle.style.display = "block";
}
//
var todo = document.querySelector(".todo");
var todoList = document.querySelector(".todoList");
var addBtn = document.querySelector(".addBtn");
addBtn.onclick = function() {
var li = document.createElement("li");
li.innerHTML = todo.value;
todo.value = ""; //사용자입력값 초기화
//li.innerHTML = todo.value + "<button onclick='remove(this);'>삭제</button>"; //사용자입력값
//btn => 인라인, 익명함수, addEventListener
var btn = document.createElement("button");
btn.innerHTML = "더블클릭삭제";
btn.ondblclick = remove;
li.appendChild(btn);
//btn2 - 아래로
var btn2 = document.createElement("button");
btn2.innerHTML = "아래로";
btn2.addEventListener("click", down );
li.appendChild(btn2);
//btn3 - 위로
var btn3 = document.createElement("button");
btn3.innerHTML = "위로";
btn3.addEventListener("click", up);
li.appendChild(btn3);
todoList.appendChild(li);
}
//삭제기능
function remove() {
this.parentElement.remove();
}
//아래로
function down() {
var current = this.parentElement;
var next = current.nextElementSibling;
//...
if(confirm("이동하시겠습니까?") ) {
todoList.insertBefore(next , current);
}
}
//위로
function up() {
var current = this.parentElement;
var prev = current.previousElementSibling;
//.....
if(confirm("이동 하시겠습니까?")) {
todoList.insertBefore(current, prev);
}
}
//전체삭제기능.
var delAll = document.querySelector(".delAll");
delAll.onclick = function() {
//클릭시에 태그를 얻음
var lis = document.querySelectorAll(".todoList > li");
for(var i = 0; i < lis.length; i++) {
lis[i].remove();
}
}
</script>
</body>
</html>
-결과
#클래스 속성 제어하기
*태그.className
-클래스 이름들을 문자열 형태로 얻어옴
*태그.classList
-클래스 이름들을 배열 형태로 얻어옴
*현재 태그에서 사용할 수 있는 함수들이 나옴.
*클래스를 제어하는데 꼭 알아야하는함수들.
-add("클래스명)
-remove("클래스명"
-contains("클래스명")
-toggle("클래스명")
이정도만 알면됨.
*이벤트는 ID에 걸어준다.
-클래스의 속성을 공부하면서 보았듯이. 클래스의 해당 속성명은 때에 따라서 있기도 하고 없어질 수도 있기 때문에,
즉 이후로 변경이 있을 수 있기 때문에.
변경이 거의 없는 ID 속성의 값에다가 이벤트를 달아준다.
*아래 코드는 토글에 관해서 중점적으로 봐보기.
<!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>
<button id="btn" class="btn btn-default">버튼</button>
<script>
var btn = document.getElementById("btn");
btn.onclick = function() {
//태그에 속성변경-->
//console.log( btn.class ); //클래스는 키워드라 안됩니다.
// console.dir(btn);
// console.log( btn.className ); //클래스명을 얻음
// console.log( btn.classList ); //클래스명을 배열로 얻음
// btn.classList.add( "newBtn" ); //클래스명 추가
// btn.classList.remove("btn-default"); //클래스명 삭제
// if(btn.classList.contains("btn") ){
// console.log("btn 클래스는 존재함");
// }
btn.classList.toggle("aaa"); //있으면 제거, 없으면 추가
}
</script>
<hr>
<h3>하나의 버튼으로 두가지 작업을 처리하기(toggle)</h3>
<button class="toggle" id="toggle">토글버튼</button>
<style>
.add {color: aqua;}
</style>
<script>
var toggle = document.getElementById("toggle");
toggle.onclick = function() {
//css, class제거
// if(toggle.classList.contains("add") ) { //add가 포함 되어있다면
// toggle.style.color = "black"; //색상변경
// toggle.classList.remove("add"); //클래스제거
// } else {
// toggle.style.color = "aqua";
// toggle.classList.add("add");
// }
toggle.classList.toggle("add");
}
</script>
</body>
</html>
* 주의할것.
다른 속성의 값들을 볼 때처럼 클래스 값을 보려고 하면 undefined가 뜸.
클래스는 키워드이기 때문이다.
<기억할것>
# 함수 관련 내용
*함수를 변수에 담아서 실행한다는 개념일 땐
변수 = 함수이름;
ex) 태그.onclick = 함수명; // 함수를 onclick이라는 속성에 담아준다는 상황임.
*함수를 호출해서 사용한다는 개념일 땐
ex)
<태그 onclick="함수명();"></태그> //onclick 의 값자리에 함수를 호출해서 사용한다는 상황임.
오늘 이둘의 차이가 많이 헷갈렸음.
# confirm("내용")
*confirm() 을 사용하면 위의 사진처럼 확인, 취소 물음이 나오고
확인을 누르면 true , 취소를 누르면 false 를 반환해줌.
이를 이용해서 로직을 처리해 나갈 수 있다. 기억해두자.
#console.dir(x); // 태그에 사용할 수 있는 속성이 무엇이 있는지 모두 출력해줌.