$찾은요소.childNodes;
$찾은요소.children;
$찾은요소.firstChild;
$찾은요소.firstElementChild;
$찾은요소.lastElementChild;
$찾은요소.hasChildNodes();
Code
<!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>
<ul id="fruits">
<li class="apple">APPLE</li>
<li class="banana">BANANA</li>
<li class="grape">GRAPE</li>
</ul>
<div id="test">
</div>
<script>
// 노드 탐색 기점이 되는 ul요소 취득
const $fruits = document.getElementById('fruits');
// 기준 노드의 모든 자식 노드를 탐색 (텍스트 노드 포함)
const $childNodes = $fruits.childNodes;
console.log($childNodes);
// 기준 노드의 모든 자식 노드를 탐색 (텍스트 노드 제외)
const $children = $fruits.children;
console.log($children);
// 기준 노드의 첫번째 자식 노드를 탐색
// firstChild는 텍스트 노드가 나올 가능성이 존재
const $firstChild = $fruits.firstChild;
console.log($firstChild);
console.log('first-element-child : ' + $fruits.firstElementChild);
console.log('last-element-child : ' + $fruits.lastElementChild);
// 기준 노드에 자식 노드가 있는지 여부 확인
// 텍스트 노드가 있을 시 true가 나올 수 있음
const $test = document.getElementById('test');
console.log($test.hasChildNodes());
// 텍스트 노드를 제외한 요소 노드의 여부 확인
// 자식 요소 노드를 취한 뒤 length 값을 논리로 바꾸어서 확인
console.log(!!$test.children.length);
</script>
</body>
</html>
$찾은요소.parentNode;
$찾은요소.previouseElementSibling;
$찾은요소.nextElementSibling;
Code
<!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 class="wrap">
<ul id="fruits">
<li class="apple">APPLE</li>
<li class="banana">BANANA</li>
<li class="grape">GRAPE</li>
</ul>
</div>
<table id="board">
<tr>
<td>A</td>
<td>B</td>
</tr>
<tr>
<td>C</td>
<td>D</td>
</tr>
</table>
<script>
const $banana = document.querySelector('.banana');
// 부모 노드 탐색
const $parent = $banana.parentNode;
console.log($parent);
const $div = $banana.parentNode.parentNode;
// div는 banana요소의 부모의 부모이므로
console.log($div);
// 이전 형제노드 탐색
const $prev = $banana.previousElementSibling;
console.log($prev);
// 다음 형제노드 탐색
const $next = $banana.nextElementSibling;
console.log($next);
// next의 다음 형제노드가 없어서 null이 옴
const $next2 = $next.nextElementSibling;
console.log($next2);
const $board = document.getElementById('board');
console.log($board.children);
// table 태그는 자식 태그로 tbody라는 태그를 자동으로 삽입하기 때문에
// 다른 요소를 가져오기 위해서는 더 밑으로 내려가야함
const $tbody = $board.children;
console.log($tbody[0].children);
// 이제는 tr두개가 뜸
</script>
</body>
</html>
$찾은요소.textContent;
Code
<!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 id="greeting">
Hello
<span>World</span>
</div>
<script>
const $div = document.getElementById('greeting');
// console.log($div.childNodes[0].nodeValue);
console.log($div.textContent)
// div 태그안에 있는 모든 텍스트만 가져와라 (마크업 제외)
$div.textContent = '<span>안녕</span>하세요';
// 태그를 작성해도 텍스트로 인식
</script>
</body>
</html>
문자열 형태로 tag와 text를 작성하게 되면 실제 페이지에 노드를 추가할 수 있음
$찾은요소.innerHTML;
$찾은요소.innerHTML += ‘추가할 것’;
innerHTML로 노드를 제어하면 보안과 성능에 문제가 있음
Code
<!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>
<ul id="fruits">
<li class="apple">Apple</li>
</ul>
<script>
const $fruits = document.getElementById('fruits');
console.log($fruits.innerHTML);
// 태그가 모두 포함됨
// 노드 추가
$fruits.innerHTML += '<li class="banana">BANANA</li>';
// li의 apple 뒤에 노드 추가
$fruits.innerHTML = '';
console.log(!!$fruits.children.length);
/*
innerHTML로만 노드를 제어하면 안됨
왜냐면 보안과 성능에 문제가 있음
그래서 HTML 변환이 필요한 문자열에만 사용하는게 좋음
*/
</script>
</body>
</html>
document.createElement(’tag name’);
생성노드.textContet = ‘텍스트';
부모노드.appendChild(생성노드);
Code
<!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>
<ul id="fruits">
<li>Apple</li>
</ul>
<script>
const $fruits = document.getElementById('fruits');
// 요소 노드 생성
const $newLi = document.createElement('li');
// 텍스트 삽입
$newLi.textContent = 'Banana';
// ul에 추가
$fruits.appendChild($newLi);
</script>
</body>
</html>
live DOM에 가상의 DOM을 반복적으로 넣는 행위는 메모리 cost를 높이기 때문에 가상의 DOM을 생성해서 한번만 live DOM에 넣으면 메모리 cost 절약 가능
document.createDocumentFragment();
Code
<!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>
<ul id="fruits">
</ul>
<script>
// live DOM : 사전에 미리 렌더링 되어 있는 요소 노드 (실제로 만들어져있는 노드)
const $fruits = document.getElementById('fruits');
const fruitName = ['Apple', 'Banana', 'Grape', 'Orange'];
/*
이미 활성화된 live DOM에 반복해서 가상 DOM을 추가하는 것은 메모리상에서 높은 코스트가 발생
활성화된 DOM을 변경 조작하는 것은 가능한 한 횟수를 줄여야함
*/
// li에 배열의 값을 반복으로 넣어줌
// for (let f of fruitName){
// const $li = document.createElement('li');
// $li.textContent = f;
// $fruits.appendChild($li);
// }
// 가상의 부모 DOM생성 다른 노드를 담는 임시 컨테이너 역할을 하는 가상 DOM 객체
const $frag = document.createDocumentFragment();
for (let f of fruitName) {
const $li = document.createElement('li');
$li.textContent = f;
$frag.appendChild($li);
// 가상 DOM인 frag에 li에 넣어주고
}
$fruits.appendChild($frag);
// 마지막으로 진짜 DOM에 가상 DOM을 한번만 넣어줌
</script>
</body>
</html>
appendChild()와 다르게 삽입 위치 설정 가능
$찾은요소.insertBefore(삽입하고 싶은 요소, 이동의 기준이 될 요소);
Code
<!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>
<ul id="fruits">
<li>Apple</li>
<li>Banana</li>
<li>Grape</li>
</ul>
<script>
const $fruits = document.getElementById('fruits');
const $li = document.createElement('li');
$li.textContent = 'Mango';
// 두번째 매개값으로 전달된 노드는 반드시 insertBefore를 호출한 노드의 자식이여야함
$fruits.insertBefore($li, $fruits.lastElementChild);
// 이미 배치된 DOM을 다시 한번 insertBefore하면 노드가 이동
const $banana = document.querySelector('#fruits > li:nth-child(2)');
$fruits.insertBefore($banana, $fruits.firstElementChild);
</script>
</body>
</html>
$찾은요소.cloneNode();
$찾은요소.cloneNode(true);
Code
<!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>
<ul id="fruits">
<li>Apple</li>
</ul>
<script>
const $fruits = document.getElementById('fruits');
const $apple = $fruits.firstElementChild;
// apple의 사본 생성 (얕은 복사 : 자기 자신 노드만 복사)
const $shallowClone = $apple.cloneNode();
console.log($shallowClone);
$shallowClone.textContent = $apple.textContent;
// apple의 text를 shallowclone에 넣어줌
$fruits.appendChild($shallowClone);
// fruit에 값을 넣어줌
// apple의 사본 생성 (깊은 복사 : 자기 자신을 포함한 모든 자손 노드를 복사)
const $deepClone = $apple.cloneNode(true);
$fruits.appendChild($deepClone);
// ul을 깊은 복사
const $ulClone = $fruits.cloneNode(true);
$fruits.appendChild($ulClone);
</script>
</body>
</html>
$찾은요소. replaceChild(교체할 값, 교체 대상);
$찾은요소.removeChild(삭제할 값);
Code
<!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>
<ul id="fruits">
<li>Apple</li>
<li>Banana</li>
</ul>
<script>
const $fruits = document.getElementById('fruits');
// 요소 추가
const $mango = document.createElement('li');
// 요소를 먼저 만듬
$mango.textContent = 'Mango';
// 내부 값 입력
$fruits.replaceChild($mango, $fruits.firstElementChild);
// fruits의 첫번째 자식을 mango로 교체
$fruits.removeChild($fruits.lastElementChild);
// fruits의 마지막 자식을 삭제
</script>
</body>
</html>