노드 탐색
1 ) 공백 텍스트 노드
- HTML 요소 사이의 공백문자는 텍스트 노드를 생성함.
- 이를 공백 텍스트 노드라고 함.
39-26
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
<li class="apple">Apple</li>
<li class="banana">Banana</li>
<li class="orange">Orange</li>
</ul>
</body>
</html>
2 ) 자식 노드 탐색
프로퍼티 | 설명 |
Node.prototype.childNodes | 자식 노드를 모두 탐색하여 DOM 컬렉션 객체인 NodeList에 담아 반환한다. childNodes 프로퍼티가 반환한 NodeList에는 요소 노드뿐만 아니라 텍스트 노드도 포함되어 있을 수 있다. |
Element.prototype.children | 자식 노드 중에서 요소 노드만 모두 탐색하여 DOM 컬렉션 객체인 HTMLCollection에 담아 반환한다. children 프로퍼티가 반환한 HTMLCollection에는 텍스트 노드가 포함되지 않는다. |
Node.prototype.firstChild | 첫 번째 자식 노드를 반환한다. firstChild 프로퍼티가 반환한 노드는 텍스트 노드이거나 요소 노드다. |
Node.prototype.lastChild | 마지막 자식 노드를 반환한다. lastChild 프로퍼티가 반환한 노드는 텍스트 노드이거나 요소 노드다. |
Element.prototype.firstElementChild | 첫 번째 자식 요소 노드를 반환한다. firstElementChild 프로퍼티는 요소 노드만 반환한다. |
Element.prototype.lastElementChild | 마지막 자식 요소 노드를 반환한다. lastElementChild 프로퍼티는 요소 노드만 반환한다. |
39-28
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
<li class="apple">Apple</li>
<li class="banana">Banana</li>
<li class="orange">Orange</li>
</ul>
</body>
<script>
// 노드 탐색의 기점이 되는 #fruits 요소 노드를 취득한다.
const $fruits = document.getElementById('fruits');
// #fruits 요소의 모든 자식 노드를 탐색한다.
// childNodes 프로퍼티가 반환한 NodeList에는 요소 노드뿐만 아니라 텍스트 노드도 포함되어 있다.
console.log($fruits.childNodes);
// NodeList(7) [text, li.apple, text, li.banana, text, li.orange, text]
// #fruits 요소의 모든 자식 노드를 탐색한다.
// children 프로퍼티가 반환한 HTMLCollection에는 요소 노드만 포함되어 있다.
console.log($fruits.children);
// HTMLCollection(3) [li.apple, li.banana, li.orange]
// #fruits 요소의 첫 번째 자식 노드를 탐색한다.
// firstChild 프로퍼티는 텍스트 노드를 반환할 수도 있다.
console.log($fruits.firstChild); // #text
// #fruits 요소의 마지막 자식 노드를 탐색한다.
// lastChild 프로퍼티는 텍스트 노드를 반환할 수도 있다.
console.log($fruits.lastChild); // #text
// #fruits 요소의 첫 번째 자식 노드를 탐색한다.
// firstElementChild 프로퍼티는 요소 노드만 반환한다.
console.log($fruits.firstElementChild); // li.apple
// #fruits 요소의 마지막 자식 노드를 탐색한다.
// lastElementChild 프로퍼티는 요소 노드만 반환한다.
console.log($fruits.lastElementChild); // li.orange
</script>
</html>
3 ) 자식 노드 존재 확인
- Node.prototype.hasChildNodes
- 자식이 존재하면 true, 존재하지 않으면 false 반환
- 단, 텍스트 노드를 포함하여 자식 노드의 존재 확인.
39-29
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
</ul>
</body>
<script>
// 노드 탐색의 기점이 되는 #fruits 요소 노드를 취득한다.
const $fruits = document.getElementById('fruits');
// #fruits 요소에 자식 노드가 존재하는지 확인한다.
// hasChildNodes 메서드는 텍스트 노드를 포함하여 자식 노드의 존재를 확인한다.
console.log($fruits.hasChildNodes()); // true
</script>
</html>
- 텍스트 노드가 아닌 요소 노드가 존재하는지 확인하려면 children.length 또는 Element 인터페이스의 childElementCount 사용.
39-30
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
</ul>
</body>
<script>
// 노드 탐색의 기점이 되는 #fruits 요소 노드를 취득한다.
const $fruits = document.getElementById('fruits');
// hasChildNodes 메서드는 텍스트 노드를 포함하여 자식 노드의 존재를 확인한다.
console.log($fruits.hasChildNodes()); // true
// 자식 노드 중에 텍스트 노드가 아닌 요소 노드가 존재하는지는 확인한다.
console.log(!!$fruits.children.length); // 0 -> false
// 자식 노드 중에 텍스트 노드가 아닌 요소 노드가 존재하는지는 확인한다.
console.log(!!$fruits.childElementCount); // 0 -> false
</script>
</html>
4 ) 요소 노드의 텍스트 노드 탐색
- 요소 노드의 텍스트 노드는 요소 노드의 자식 노드다.
- 따라서 요소 노드의 텍스트 노드는 firstChild 프로퍼티로 접근할 수 있음.
39-31
<!DOCTYPE html>
<html>
<body>
<div id="foo">Hello</div>
<script>
// 요소 노드의 텍스트 노드는 firstChild 프로퍼티로 접근할 수 있다.
console.log(document.getElementById('foo').firstChild); // #text
</script>
</body>
</html>
5 ) 부모 노드 탐색
- Node.prototype.parentNode
- 텍스트 노드는 DOM 트리의 최종단 노드인 리프 노드 이므로 부모 노드가 텍스트 노드인 경우는 없음.
39-32
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
<li class="apple">Apple</li>
<li class="banana">Banana</li>
<li class="orange">Orange</li>
</ul>
</body>
<script>
// 노드 탐색의 기점이 되는 .banana 요소 노드를 취득한다.
const $banana = document.querySelector('.banana');
// .banana 요소 노드의 부모 노드를 탐색한다.
console.log($banana.parentNode); // ul#fruits
</script>
</html>
6 ) 형제 노드 탐색
- 어트리뷰트 노드는 요소 노드와 연결되어 있지만 부모 노드가 같은 형제 노드가 아니기 때문에 반환되지 않음.
- 텍스트 노드 또는 요소 노드만 반환함.
프로퍼티 | 설명 |
Node.prototype.previousSibling | 부모 노드가 같은 형제 노드 중에서 자신의 이전 형제 노드를 탐색하여 반환한다. previousSibling 프로퍼티가 반환하는 형제 노드는 요소 노드 뿐만 아니라 텍스트 노드일 수도 있다. |
Node.prototype.nextSibling | 부모 노드가 같은 형제 노드 중에서 자신의 다음 형제 노드를 탐색하여 반환한다. nextSibling 프로퍼티가 반환하는 형제 노드는 요소 노드뿐만 아니라 텍스트 노드일 수도 있다. |
Element.prototype.previousElementSibling | 부모 노드가 같은 형제 요소 노드 중에서 자신의 이전 형제 요소 노드를 탐색하여 반환한다. previousElementSibling 프로퍼티는 요소 노드만 반환한다. |
Element.prototype.nextElementSibling | 부모 노드가 같은 형제 요소 노드 중에서 자신의 다음 형제 요소 노드를 탐색하여 반환한다. nextElementSibling 프로퍼티는 요소 노드만 반환한다. |
39-33
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
<li class="apple">Apple</li>
<li class="banana">Banana</li>
<li class="orange">Orange</li>
</ul>
</body>
<script>
// 노드 탐색의 기점이 되는 #fruits 요소 노드를 취득한다.
const $fruits = document.getElementById('fruits');
// #fruits 요소의 첫 번째 자식 노드를 탐색한다.
// firstChild 프로퍼티는 요소 노드뿐만 아니라 텍스트 노드를 반환할 수도 있다.
const { firstChild } = $fruits;
console.log(firstChild); // #text
// #fruits 요소의 첫 번째 자식 노드(텍스트 노드)의 다음 형제 노드를 탐색한다.
// nextSibling 프로퍼티는 요소 노드뿐만 아니라 텍스트 노드를 반환할 수도 있다.
const { nextSibling } = firstChild;
console.log(nextSibling); // li.apple
// li.apple 요소의 이전 형제 노드를 탐색한다.
// previousSibling 프로퍼티는 요소 노드뿐만 아니라 텍스트 노드를 반환할 수도 있다.
const { previousSibling } = nextSibling;
console.log(previousSibling); // #text
// #fruits 요소의 첫 번째 자식 요소 노드를 탐색한다.
// firstElementChild 프로퍼티는 요소 노드만 반환한다.
const { firstElementChild } = $fruits;
console.log(firstElementChild); // li.apple
// #fruits 요소의 첫 번째 자식 요소 노드(li.apple)의 다음 형제 노드를 탐색한다.
// nextElementSibling 프로퍼티는 요소 노드만 반환한다.
const { nextElementSibling } = firstElementChild;
console.log(nextElementSibling); // li.banana
// li.banana 요소의 이전 형제 요소 노드를 탐색한다.
// previousElementSibling 프로퍼티는 요소 노드만 반환한다.
const { previousElementSibling } = nextElementSibling;
console.log(previousElementSibling); // li.apple
</script>
</html>
노드 정보 취득
프로퍼티 | 설명 |
Node.prototype.nodeType | 노드 객체의 종류, 즉 노드 타입을 나타내는 상수를 반환한다. 노드 타입 상수는 Node에 정의되어 있다. |
- Node.Element_NODE: 요소 노드 타입을 나타내는 상수 1을 반환
- Node.TEXT_NODE : 텍스트 노드 타입을 나타내는 상수 3을 반환
- Node.DOCUMENT_NODE : 문서 노드 타입을 나타내는 상수 9를 반환 | | Node.prototype.nodeName | 노드의 이름을 문자열로 반환한다.
- 요소 노드 : 대문자 문자열로 태그 이름(”UL”, “LI” 등)을 반환
- 텍스트 노드 : 문자열 “#text”를 반환
- 문서 노드 : 문자열 “#document”를 반환 |
39-34
<!DOCTYPE html>
<html>
<body>
<div id="foo">Hello</div>
</body>
<script>
// 문서 노드의 노드 정보를 취득한다.
console.log(document.nodeType); // 9
console.log(document.nodeName); // #document
// 요소 노드의 노드 정보를 취득한다.
const $foo = document.getElementById('foo');
console.log($foo.nodeType); // 1
console.log($foo.nodeName); // DIV
// 텍스트 노드의 노드 정보를 취득한다.
const $textNode = $foo.firstChild;
console.log($textNode.nodeType); // 3
console.log($textNode.nodeName); // #text
</script>
</html>
요소 노드의 텍스트 조작
1 ) nodeValue
- 지금까지 살펴본 노드 탐색, 노드 정보 프로퍼티는 모두 읽기 전용 접근자 프로퍼티.
- Node.prototype.nodeValue 프로퍼티는 setter와 getter 모두 존재하는 접근자 프로퍼티.
- 따라서 nodeValue 프로퍼티는 참조와 할당이 모두 가능.
- 노드 객체의 nodeValue 프로퍼티를 참조하면 노드 객체의 값(텍스트 노드의 텍스트)을 반환함.
39-35
<!DOCTYPE html>
<html>
<body>
<div id="foo">Hello</div>
</body>
<script>
// 문서 노드의 nodeValue 프로퍼티를 참조한다.
console.log(document.nodeValue); // null
// 요소 노드의 nodeValue 프로퍼티를 참조한다.
const $foo = document.getElementById('foo');
console.log($foo.nodeValue); // null
// 텍스트 노드의 nodeValue 프로퍼티를 참조한다.
const $textNode = $foo.firstChild;
console.log($textNode.nodeValue); // Hello
</script>
</html>
- 이처럼 텍스트 노드의 nodeValue 프로퍼티를 참조할 때만 텍스트를 반환함.
- 텍스트 노드의 nodeValue 프로퍼티에 값을 할당하면 텍스트를 변경할 수 있음.
- 1 ) 텍스트를 변경할 요소 노드를 취득한 다음, 취득한 요소 노드의 텍스트 노드를 탐색.
- 텍스트 노드는 요소 노드의 자식 노드이므로 firstChild 프로퍼티를 사용하여 탐색.
- 2 ) 탐색한 텍스트 노드의 nodeValue 프로퍼티를 사용하여 텍스트 노드의 값을 변경.
39-36
<!DOCTYPE html>
<html>
<body>
<div id="foo">Hello</div>
</body>
<script>
// 1. #foo 요소 노드의 자식 노드인 텍스트 노드를 취득한다.
const $textNode = document.getElementById('foo').firstChild;
// 2. nodeValue 프로퍼티를 사용하여 텍스트 노드의 값을 변경한다.
$textNode.nodeValue = 'World';
console.log($textNode.nodeValue); // World
</script>
</html>
2 ) textContent
- Node.prototype.textContent 는 setter와 getter 모두 존재하는 접근자 프로퍼티
- 요소 노드의 텍스트와 모든 자손 노드의 텍스트를 모두 취득하거나 변경함.
39-37
<!DOCTYPE html>
<html>
<body>
<div id="foo">Hello <span>world!</span></div>
</body>
<script>
// #foo 요소 노드의 텍스트를 모두 취득한다. 이때 HTML 마크업은 무시된다.
console.log(document.getElementById('foo').textContent); // Hello world!
</script>
</html>
- 텍스트 노드가 아닌 노드의 nodeValue 프로퍼티는 null을 반환하므로 의미가 없음.
- nodeValue 프로퍼티를 사용하면 textContent 프로퍼티를 사용할 때와 비교해서 코드가 더 복잡.
39-38
<!DOCTYPE html>
<html>
<body>
<div id="foo">Hello <span>world!</span></div>
</body>
<script>
// #foo 요소 노드는 텍스트 노드가 아니다.
console.log(document.getElementById('foo').nodeValue); // null
// #foo 요소 노드의 자식 노드인 텍스트 노드의 값을 취득한다.
console.log(document.getElementById('foo').firstChild.nodeValue); // Hello
// span 요소 노드의 자식 노드인 텍스트 노드의 값을 취득한다.
console.log(document.getElementById('foo').lastChild.firstChild.nodeValue); // world!
</script>
</html>
- 만약 자식 요소 노드가 없고 텍스트만 존재한다면 firstChild.nodeValue와 textContent 프로퍼티는 같은 결과를 반환함.
- 이 경우 textContent 가 코드가 더 간단함.
39-39
<!DOCTYPE html>
<html>
<body>
<!-- 요소 노드의 콘텐츠 영역에 다른 요소 노드가 없고 텍스트만 존재 -->
<div id="foo">Hello</div>
</body>
<script>
const $foo = document.getElementById('foo');
// 요소 노드의 콘텐츠 영역에 자식 요소 노드가 없고 텍스트만 존재한다면
// firstChild.nodeValue와 textContent는 같은 결과를 반환한다.
console.log($foo.textContent === $foo.firstChild.nodeValue); // true
</script>
</html>
- textContent에 문자열을 할당하면 모든 자식 노드가 제거되고 할당한 문자열이 텍스트로 추가됨.
- 이때 HTML 마크업이 파싱되지 않음.
39-40
<!DOCTYPE html>
<html>
<body>
<div id="foo">Hello <span>world!</span></div>
</body>
<script>
// #foo 요소 노드의 모든 자식 노드가 제거되고 할당한 문자열이 텍스트로 추가된다.
// 이때 HTML 마크업이 파싱되지 않는다.
document.getElementById('foo').textContent = 'Hi <span>there!</span>';
</script>
</html>
- 참고로 textContent와 유사한 동작을 하는 innerText 프로퍼티가 있음. 하지만 사용하지 않는 것이 좋음.
- 1 ) CSS에 순종적임. 예를 들어, CSS에 의해 비표시(visibility: hidden;)로 지정된 요소 노드의 텍스트를 반환하지 않음.
- 2 ) CSS를 고려해야하므로 textContent 프로퍼티보다 느림.
DOM 조작
- DOM 조작 : 새로운 노드를 생성하여 DOM에 추가하거나 기존 노드를 삭제 또는 교체하는 것.
- DOM 조작에 의해 새로운 노드가 추가되거나 삭제되면 리플로우와 리페인트가 발생하는 원인이 되므로 성능에 영향을 줌.
1 ) innerHTML
- setter와 getter 모두 존재하는 접근자 프로퍼티.
- 요소 노드의 HTML 마크업을 취득하거나 변경함.
- 요소 노드의 콘텐츠 영역(시작 태그와 종료 태그 사이) 내에 포함된 모든 HTML 마크업을 문자열로 반환함.
39-41
<!DOCTYPE html>
<html>
<body>
<div id="foo">Hello <span>world!</span></div>
</body>
<script>
// #foo 요소의 콘텐츠 영역 내의 HTML 마크업을 문자열로 취득한다.
console.log(document.getElementById('foo').innerHTML);
// "Hello <span>world!</span>"
</script>
</html>
- textContent는 HTML 마크업을 무시하고 텍스트만 반환
- ↔ innerHTML은 HTML 마크업이 포함된 문자열을 그대로 반환.
- innterHTML에 문자열을 할당하면 모든 자식 노드가 제거되고 할당한 문자열에 포함되어 있는 HTML 마크업이 파싱되어 요소 노드의 자식 노드로 DOM에 반영됨.
39-42
<!DOCTYPE html>
<html>
<body>
<div id="foo">Hello <span>world!</span></div>
</body>
<script>
// HTML 마크업이 파싱되어 요소 노드의 자식 노드로 DOM에 반영된다.
document.getElementById('foo').innerHTML = 'Hi <span>there!</span>';
</script>
</html>
- DOM 조작가능
39-43
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
<li class="apple">Apple</li>
</ul>
</body>
<script>
const $fruits = document.getElementById('fruits');
// 노드 추가
$fruits.innerHTML += '<li class="banana">Banana</li>';
// 노드 교체
$fruits.innerHTML = '<li class="orange">Orange</li>';
// 노드 삭제
$fruits.innerHTML = '';
</script>
</html>
- 요소 노드의 innerHTML에 할당한 HTML 마크업 문자열은 렌더링 엔진에 의해 파싱되어 요소 노드의 자식으로 DOM에 반영됨.
- 이때 사용자로부터 입력받은 데이터를 그대로 프로퍼티에 할당하는 것은 **크로스 사이트 스크립팅 공격(XSS: Cross-Site Scripting Attacks)**에 취약함.
39-44
<!DOCTYPE html>
<html>
<body>
<div id="foo">Hello</div>
</body>
<script>
// innerHTML 프로퍼티로 스크립트 태그를 삽입하여 자바스크립트가 실행되도록 한다.
// HTML5는 innerHTML 프로퍼티로 삽입된 script 요소 내의 자바스크립트 코드를 실행하지 않는다.
document.getElementById('foo').innerHTML
= '<script>alert(document.cookie)</script>';
</script>
</html>
- innerHTML의 또 다른 단점은 요소 노드의 innerHTML에 HTML 마크업 문자열을 할당하는 경우 요소 노드의 모든 자식 노드를 제거하고 할당한 HTML 마크업 문자열을 파싱하여 DOM을 변경한다는 것이다.
39-46
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
<li class="apple">Apple</li>
</ul>
</body>
<script>
const $fruits = document.getElementById('fruits');
// 노드 추가
$fruits.innerHTML += '<li class="banana">Banana</li>';
</script>
</html>
- 위 예제는 #fruits 요소의 모든 자식 노드(li.apple)를 제거하고 새롭게 요소 노드 li.apple과 li.banana를 생성하여 #fruits 요소의 자식 요소로 추가함.
- 이는 효율적이지 않음.
- 새로운 요소를 삽입할 때 삽입될 위치를 지정할 수 없음.
39-49
<ul id="fruits">
<li class="apple">Apple</li>
<li class="orange">Orange</li>
</ul>
- apple과 orange 사이에 새로운 요소를 삽입하고 싶은 경우 삽입 위치를 지정할 수 없음.
2 ) insertAdjacentHTML 메서드
- 기존 요소를 제거하지 않으면서 위치를 지정해 새로운 요소를 삽입
- 두번째 인수로 전달한 HTML 마크업 문자열을 파싱하고 그 결과로 생성된 노드를 첫번째 인수로 전달한 위치에 삽입하여 DOM에 반영함.
- 첫번째 인수로 전달할 수 있는 문자열은 ‘beforebegin’, ‘afterbegin’, ‘beforeend’, ‘afterend’ 4가지임.
39-50
<!DOCTYPE html>
<html>
<body>
<!-- beforebegin -->
<div id="foo">
<!-- afterbegin -->
text
<!-- beforeend -->
</div>
<!-- afterend -->
</body>
<script>
const $foo = document.getElementById('foo');
$foo.insertAdjacentHTML('beforebegin', '<p>beforebegin</p>');
$foo.insertAdjacentHTML('afterbegin', '<p>afterbegin</p>');
$foo.insertAdjacentHTML('beforeend', '<p>beforeend</p>');
$foo.insertAdjacentHTML('afterend', '<p>afterend</p>');
</script>
</html>
3 ) 노드 생성과 추가
- innerHTML, insertAdjacentHTML 메서드는 HTML 마크업 문자열을 파싱하여 노드를 생성하고 DOM에 반영함.
- DOM은 노드를 직접 생성/삽입/삭제/치환하는 메서드도 제공함.
39-51
<!DOCTYPE html>
<html>
<body>
<ul id="fruits">
<li>Apple</li>
</ul>
</body>
<script>
const $fruits = document.getElementById('fruits');
// 1. 요소 노드 생성
const $li = document.createElement('li');
// 2. 텍스트 노드 생성
const textNode = document.createTextNode('Banana');
// 3. 텍스트 노드를 $li 요소 노드의 자식 노드로 추가
$li.appendChild(textNode);
// 4. $li 요소 노드를 #fruits 요소 노드의 마지막 자식 노드로 추가
$fruits.appendChild($li);
</script>
</html>
4 ) 복수의 노드 생성과 추가
- 여러 개의 요소 노드를 생성하여 DOM에 추가
39-58
<!DOCTYPE html>
<html>
<body>
<ul id="fruits"></ul>
</body>
<script>
const $fruits = document.getElementById('fruits');
['Apple', 'Banana', 'Orange'].forEach(text => {
// 1. 요소 노드 생성
const $li = document.createElement('li');
// 2. 텍스트 노드 생성
const textNode = document.createTextNode(text);
// 3. 텍스트 노드를 $li 요소 노드의 자식 노드로 추가
$li.appendChild(textNode);
// 4. $li 요소 노드를 #fruits 요소 노드의 마지막 자식 노드로 추가
$fruits.appendChild($li);
});
</script>
</html>
- 여러 번 DOM을 변경 === 높은 비용
- 컨테이너 요소 사용 === DOM 1번 변경
39-59
<!DOCTYPE html>
<html>
<body>
<ul id="fruits"></ul>
</body>
<script>
const $fruits = document.getElementById('fruits');
// 컨테이너 요소 노드 생성
const $container = document.createElement('div');
['Apple', 'Banana', 'Orange'].forEach(text => {
// 1. 요소 노드 생성
const $li = document.createElement('li');
// 2. 텍스트 노드 생성
const textNode = document.createTextNode(text);
// 3. 텍스트 노드를 $li 요소 노드의 자식 노드로 추가
$li.appendChild(textNode);
// 4. $li 요소 노드를 컨테이너 요소의 마지막 자식 노드로 추가
$container.appendChild($li);
});
// 5. 컨테이너 요소 노드를 #fruits 요소 노드의 마지막 자식 노드로 추가
$fruits.appendChild($container);
</script>
</html>
- 불필요한 div가 추가됨
39-60
<ul id="fruits">
<div>
<li>apple</li>
<li>banana</li>
<li>orange</li>
</div>
</ul>
- DocumentFragment 사용
39-61
<!DOCTYPE html>
<html>
<body>
<ul id="fruits"></ul>
</body>
<script>
const $fruits = document.getElementById('fruits');
// DocumentFragment 노드 생성
const $fragment = document.createDocumentFragment();
['Apple', 'Banana', 'Orange'].forEach(text => {
// 1. 요소 노드 생성
const $li = document.createElement('li');
// 2. 텍스트 노드 생성
const textNode = document.createTextNode(text);
// 3. 텍스트 노드를 $li 요소 노드의 자식 노드로 추가
$li.appendChild(textNode);
// 4. $li 요소 노드를 DocumentFragment 노드의 마지막 자식 노드로 추가
$fragment.appendChild($li);
});
// 5. DocumentFragment 노드를 #fruits 요소 노드의 마지막 자식 노드로 추가
$fruits.appendChild($fragment);
</script>
</html>
5 ) 노드 삽입
5-1 ) 마지막 노드로 추가
- appendChild
5-2 ) 지정한 위치에 노드 삽입
- insertBefore(newNode, childNode)
6 ) 노드 이동
- appendChild, insertBefore
7 ) 노드 복사
- cloneNode([deep: true | false])
8 ) 노드 교체
- replaceChild(newChild, oldChild)
9 ) 노드 삭제
- removeChild(child)
어트리뷰트
1 ) 어트리뷰트 노드와 attributes 프로퍼티
- HTML 문서가 파싱될 때 HTML 요소의 어트리뷰트는 어트리뷰트 노드로 변환되어 요소 노드와 연결됨. 이때 HTML 어트리뷰트당 하나의 어트리뷰트 노드가 생성됨.
- 이때 모든 어트리뷰트 노드의 참조는 유사 배열 객체이자 이터러블인 NameNodemap 객체에 담겨서 요소 노드의 attributes 프로퍼티에 저장됨.
2 ) HTML 어트리뷰트 조작
- Element.prototype.getAttribute/setAttribute 참조/변경
- hasAttribute 특정 어트리뷰트 존재 확인
- removeAttribute 특정 어트리뷰트 삭제
3 ) HTML 어트리뷰트 vs. DOM 프로퍼티
- 요소 노드의 초기 상태는 어트리뷰트 노드가 관리하며, 요소 노드의 최신 상태는 DOM 프로퍼티가 관리한다.
'JS' 카테고리의 다른 글
모던 자바스크립트 Deep Dive - 타이머 (0) | 2024.02.12 |
---|---|
모던 자바스크립트 Deep Dive - 이벤트 (0) | 2024.02.11 |
모던 자바스크립트 Deep Dive - DOM 1 (0) | 2024.02.09 |
모던 자바스크립트 Deep Dive - 브라우저의 렌더링 과정 (0) | 2024.02.07 |
모던 자바스크립트 Deep Dive - Set과 Map (0) | 2024.02.05 |
댓글