-
DOM - 노드JavaScript/DOM 2022. 11. 26. 12:16
노드 탐색
- 요소노드를 취득한 다음, 취득한 요소 노드를 기점으로 DOM트리의 노드를 옮겨 다니며 부모, 형제, 자식, 노드 등을 탐색해야 할 때가 있다
- parentNode, previousSibling, nextSibling, firstChild,lastChild, childNodes 프로퍼티는 Node.prototype 이 제공하고,
프로퍼티 키에 Element가 포함된 previousElementSibling, nextElemenbSibling, firstElementChild, lastElementChild, children 프로퍼티는 Element.prototype이 제공한다
- Node.prototype는 setter없는 읽기 전용 접근자 프로퍼티
공백 테스트 노드
- HTML요소 사이의 스테이스, 탭, 줄바꿈 등의 공백 문자는 텍스트 노드를 생성 => 공백 텍스트 노드
https://go.gliffy.com/go/html5/launch
# 그림 넣기 page 702
자식 노드 탐색
프로퍼티 설명 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 프로퍼티는
요소 노드만 반환<!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="orange">Orange</li> </ul> </body> <script> // 노드 탐색의 기점이 되는 fruits 획득 const fruits = document.getElementById('fruits'); // ChildrenNodes는 Nodelist를 반환 // 요소 노드뿐만 아니라 텍스트 노드도 있다 console.log(fruits.childNodes); // // NodeList(7) [text, li.apple, text, li.banana, text, li.orange, text] // Children는 HTMLCollections를 반환 // 요소 노드만 포함되어 있다 console.log(fruits.children); // HTMLCollection(3) [li.apple, li.banana, li.orange] // firstChild프로퍼티는 텍스트 노드를 반환할 수 있다 console.log(fruits.firstChild); //text // lastChild프로퍼티는 텍스트 노드를 반환할 수 있다 console.log(fruits.lastChild); //text // firstElementChild 프로퍼티는 요소 노드만 반환 console.log(fruits.firstElementChild); // li.apple // lastElemetChild 프로퍼티는 요소 노드만 반환 console.log(fruits.lastElementChild); // li.orange </script> </html>
자식 노드 존재 확인
Node.prototype.hasChildNodes
- 자식 노드가 존재하면 true, 존재하지 않은면 false를 반환
- 텍스트 노드를 포함한 자식 노드의 존재를 확인
자식 노드 중에 텍스트 노드가 아닌 요소 노드가 존재하는지 확인하려면?!
- children.length 또는 Element 인터페이스의 childElementCount 프러퍼티사용
<!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> </body> <script> // 노드 탐색의 기점이 되는 #fruits 요소 노드를 취득 const fruits = document.getElementById('fruits'); console.log(fruits.hasChildNodes()); // true // 자식 노드 중에 텍스트 노드가 아닌 요소 노드가 존재하는지 확인 console.log(fruits.children.length); // 0 console.log(fruits.childElementCount); // 0 </script> </html>
요소 노드의 텍스트 노드 탐색
- 요소 노드의 텍스트 노드는 firstChild 프로퍼티로 접근할 수 있다. firstChild는 첫 번째 자식 노드를 반환한다
- firstChild프로퍼티가 반환한 노드는 텍스트 노드이거나 요소 노드이다
<!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="foo">Hello</div> </body> <script> // 요소 노드의 텍스트 노드는 firstChild 프로퍼티로 접근할 수 있다 console.log(document.getElementById('foo').firstChild); // #text </script> </html>
부모 노드 탐색
- Node.prototype.parentNode 프러퍼티 사용
<!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="orange">Orange</li> </ul> </body> <script> const banana = document.querySelector('.banana'); console.log(banana.parentNode); // ul#fruits </script> </html>
형제 노드 탐색
프로퍼티 설명 Node.prototype.previousSibling 부모 노드가 같은 형제 노드 중에서 이전 형제 노드를 탐색하여 반환. 요소 노드 뿐만 아니라, 텍스트 노드가 반환될 수 있음 Node.prototype.nextSibling 부모 노드가 같은 형제 노드 중에서 다음 형제 노드를 탐색하여 반환. 요소 노드 뿐만 아니라, 텍스트 노드가 반환될 수 있음 Element.prototype.previosElementSibling 부모 노드가 같은 형제 노드 중에서 이전 형제 노드를 탐색하여 반환. 요소 노드만 반환 Element.prototype.nextElementSibling 부모 노드가 같은 형제 노드 중에서 다음 형제 노드를 탐색하여 반환. 요소 노드만 반환 <!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="orange">Orange</li> </ul> </body> <script> const fruits = document.getElementById('fruits'); // firstChild 프로퍼티는 요소노드 or 텍스트 노드를 반환 const { firstChild } = fruits; console.log(firstChild); // #text // nextSibling 프로퍼티는 요소노드 or 텍스트 노드를 반환 const { nextSibling } = firstChild; console.log(nextSibling); // li.apple // prveiousibling 프로퍼티는 요소노드 or 텍스트 노드를 반환 const { previousSibling } = nextSibling; console.log(previousSibling); // #text // firstElementChild 프러퍼티는 요소노드만 반환 const { firstElementChild } = fruits; console.log(firstElementChild); // li.apple // nextElementChild 프러퍼티는 요소노드만 반환 const { nextElementSibling } = firstElementChild; console.log(nextElementSibling); // li.banana </script> </html>
노드 정보 취득
프로퍼티 설명 Node.prototype.nodeType 노드 객체의 종류, 노드 타입을 나타나는 상수를 반환
- Node.ELEMENT_NODE: 요소 노드 타입 반환, 1
- Node.TEXT_NODE: 텍스트 노드 타입 반환, 3
- Node.DOCUMENT_NODE: 문서 노드 타입을 반환, 9Node.prototype.nodeName 노드의 이름을 문자열로 반환
- 요소 노드: 대문자 문자열로 태그이름(ul, li) 을 반환
- 텍스트 노드: 문자열 '#text'를 반환
- 문서 노드: 문자열 '#documenet' 를 반환<!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="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>
요소 노드의 텍스트 조작
Node.prototype.nodeValue
- setter, getter 모두 존재하는 프로퍼티. 따라서 nodeValue는 프러퍼티는 참조와 할당이 모두 가능
- nodeValue프러퍼티를 참조하면 노드 객체의 값을 반환. 노드 객체의 값이란 텍스트 노드의 텍스트
- 텍스트 노드가 아닌, 문서노드나 요소 노드의 nonvalue 프러퍼티를 참조하면은 null를 반환
<!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="foo">Hello</div> </body> <script> // document 노드 console.log(document.nodeValue); // null // 요소 노드 const foo = document.getElementById('foo'); console.log(foo.nodeValue); // null // 텍스트 노드 const textNode = foo.firstChild; console.log(textNode.nodeValue); // Hello </script> </html>
텍스트 노드로만 텍스트에 접근이 가능하기 떄문에 요소노드나 document 노드에 nodeValue를 할당해도 아무 의미 X
따라서 요소노드에 텍스트를 바꾸려면?!
1. 텍스트를 변경할 요소 노드를 취득한 다음에, 취득한 요소 노드의 텍스트 노드를 탐색. 텍스트 노드는 요소 노드의 첫번째 자식 노드이므로 firstChild 프로퍼티를 사용하여 탐색한다 2. 텍스트 노드의 nodeValue프러퍼티를 사용하여 텍스트 노드의 값을 변경
<!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="foo">Hello</div> </body> <script> // 해당 요소를 탐색 const textNode = document.getElementById('foo').firstChild; textNode.nodeValue = 'World'; console.log(textNode.nodeValue); // World </script> </html>
Node.prototype.textContent
- setter와 getter 모두 존재하는 접근자 프로퍼티. 값을 취득, 할당 모두 가능
- 요소노드와 모든 자손 노드의 텍스트를 취득하거나 변경할 수 있다
- 요소 노드의 textContent 프로퍼티를 참조하면은 요소 노드의 콘텐츠 영역(시작 태그와 종료 태그 사이) 내의 텍스트를 반환한다 (HTMl 마크업 무시)
textContent 프로퍼티에 의한 텍스트 취득
<!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="foo">Hello<span>World!</span></div> </body> <script> // textContent를 이용하여 text를 반환 console.log(document.getElementById('foo').textContent); // HelloWorld! </script> </html>
nodeValue 프로퍼티에 의한 텍스트 취득
<!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="foo">Hello<span>World!</span></div> </body> <script> // nodevalue를 이용하여 text를 반환, nodevalue는 textnode에서만 사용할 수 있음. 따라서 textNode를 구하는게 우선 const textNode = document.getElementById('foo').childNodes; // NodeList(2) [text, span] console.log(textNode[0]); // #text console.log(textNode[0].nodeValue); // Hello console.log(textNode[1]); // span console.log(textNode[1].firstChild); // #text console.log(textNode[1].firstChild.nodeValue); // world! </script> </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 id="foo">Hello<span>World!</span></div> </body> <script> </script> </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 id="foo">Hello<span>World!</span></div> </body> <script> console.log(document.getElementById('foo').firstChild.nodeValue); // hello console.log(document.getElementById('foo').lastChild.firstChild.nodeValue); // wordl </script> </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 id="foo">Hello</div> </body> <script> // 요노소드의 컨텐츠 영역에 자식 요소 노드가 없고, 텍스트만 존재한다면?! // textContent와 firstChild.nodevalue는 같은 결과 반환 const foo = document.getElementById('foo'); console.log(foo.textContent === foo.firstChild.nodeValue); // true </script> </html>
요소노드의 textContent 프로퍼티에 문자열을 할당하면 요소 노드의 모든 자식 노드가 제거가 되고 할당한 문자열이 텍스트로 문자된다
<!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="foo">Hello <span>world!</span></div> </body> <script> document.getElementById('foo').textContent = 'Hi <span> there! </span>'; </script> </html>
cf. textContent 프러퍼티와 유사한 동작을 하는 innerText 프로퍼티가 있다. innerText 프로퍼티는 다음과 같은 이유로 사용하지 않는 것이 좋다.
- innerText 프로퍼티는 CSS에 순종적. 예를 들어, innerText 프로퍼티는 CSS에 의해 비표시(visibility: hiddden;) 로 지정된 요소 노드의 텍스트를 반환하지 않는다
- innerText 프로퍼티는 CSS를 고려해야 하므로 textContent프로퍼티보다 느리다
'JavaScript > DOM' 카테고리의 다른 글
<script>태그 위치 (0) 2023.01.11 DOM조작 (0) 2022.11.26 DOM요소에 접근하고 속성 가져오기 (0) 2022.11.23 스타일(css style)다루기 (0) 2022.11.22 속성(Attribute)와 프러퍼티(Property) (0) 2022.11.21