티스토리 뷰

getElement와 getquerySelector 두 메서드는 반환 값이 조금 다릅니다.

'document.querySelectorAll('p');
NodeList(4) [p#first, p#second, p, p]
document.getElementByTagName('p');
HTMLCollection(4) [p#first, p#second, p, p, first: p#first, second: p#second]

querySelectorAll과 getElementByTagName은 동일한 동작을 하는 것처럼 보이지만 반환값은 NodeList와 HTMLCollection으로 다릅니다. 둘 다 유사 배열 객체면서 iterable(반복가능한)인데요. 그래서 for of로 순회했었습니다.

const pList1 = document.querySelectorAll('p');
const pList2 = document.getElementsByTagName('p');

 

 

pList1은 NodeList, 배열의 길이는 4개 이고 pList2는 HTMLCollection, 배열의 길이는 4개 입니다.

이 상태에서 p를 하나 더 추가하면 pList1은 여전히 4개이고 값이 변하지 않습니다. 

pList2는 5개로 변경 되었습니다.

선언은 p를 추가하기 전에 했고 코드를 다시 작성하지 않았는데 HTMLCollection은 자동으로 반영이 되어 있습니다.

노드의 변경사항이 실시간으로 반영이 되는 것입니다. 그에 반해 NodeList는 한번 저장된 값을 계속 사용합니다.

대부분의 경우에는 이렇게 동작하는데 아닌 경우도 있습니다.

const red = document.getElementById('red');
red.parentNode;
red.parentElement;

부모 노드에 접근하기 위해서는 parentNode, parentElement로 접근할 수 있고 동일한 결과가 나옵니다.

 document.documentElement.parentNode
 #document
 
 document.documentElement.parentElement
 null

document.documentElement는 html 이고 html의 부모는 (document.documentElement.parentNode)로 하면 #document가 나오고 (document.documentElement.parentElement)로 하면 null 이 나옵니다.

이유는 parentNode는 부모 노드를 반환합니다. html의 부모 노드는 document가 되는 것입니다.

반면 parentElement는 부모 노드 중에 요소 노드만 반환합니다. Element가 요소라는 뜻이죠. 요소 노드란 말 그대로 html 태그로 이루어진 요소를 의미합니다. 

 

노드는 다양한 타입이 있습니다. 문서를 살펴보면 총 12개가 있고 그 중에서 5,6,11번은 더 이상 사용되지 않습니다. 다 외울 필요는 없고 자주 사용되는 타입들만 보면 1번(NODE.ELEMENT_NODE)이 방금 언급된 요소 노드입니다. p나 div같은 html 요소를 말합니다.

2번(NODE.ATTRIBUTE_NODE)은 이미지 태그에 alt 값 같은 것입니다.

3번(NODE.TEXT_NODE) 말그대로 텍스트

8번(NODE.COMMENT_NODE) 주석

9번(NODE.DOCUMENT_NODE) DOCUMENT입니다.

 

다시 돌아와서 parentNode는 부모인 노드 중 모든 노드를 반환합니다. 반면 parentElement는 부모인 노드 중 요소 노드만 반환합니다.

document는 요소 노드가 아니기 때문에 html에서 부모 요소 노드를 찾으면 null이 나옵니다.

 

const ul = document.getElementById('color');

자식 노드에 접근하기 위해서는 childNodes(자식 노드 전부), children(자식 노드 중 요소 노드만 반환)을 이용합니다.

ul.childNodes;
NodeList(9) [text, li#red, text, comment, text, li#blue, text, li#green, text]
ul.children;
HTMLCollection(3) [li#red, li#blue, li#green, red: li#red, blue: li#blue, green: li#green]

childNode는 li 뿐만 아니라 text를 포함한 모든 타입의 노드를 반환합니다. ul과 li 사이에 text가 없는데 text 노드가 나오는 이유는 html이 파싱된 후에 도움을 생성할 때 생기는 공백 문자 입니다. 스페이스나 줄바꿈도 text 노드로 함께 잡힙니다.

코드에서 줄바꿈이 되고 li가 있고 comment가 있고 줄바꿈과 li, 이런 식으로 해서 9개가 나온 겁니다. 공백을 없애면 NodeList는 4개가 됩니다. html 요소에 접근할 때는 요소 노드만(children) 가급적 선택하는게 편합니다.

 

ul.childNodes하면 NodeList가 뜨고 ul.children하면 HTMLCollection이라고 뜹니다.

NodeList는 모든 타입의 노드 그리고 HTMLCollection은 요소 타입의 노드들만 모입니다.

 

HTMLCollection은 노드의 변경사항이 실시간으로 반영되고 NodeList는 실시간으로 반영되지 않지만 예외적으로 childeNodes는 HTILCollection같이 실시간 반응이 동작합니다.

 

ul.firstChild;
#text
ul.lastChild;
#text

ul.firstElementChild;
<li id='red'>...</li>
ul.lastElementChild;
<li id='green'>...</li>

ul.firstChild하면 첫번 째 노드를 가져오고 lastChild하면 마지막 노드를 가져오고

firstElementChild와 lastElementChild는 첫 번째와 마지막의 요소 노드만 가지고 옵니다.

 

형제 노드는 이전 형제와 다음 형제로 나뉩니다.

const blue = document.getElementById('blue');
blue.previousSibling;
#text

blue.nextSibling;
#text

previousSibling과 nextSibling은 헝제 노드 중 모든 타입을 가져오는 것입니다.

blue.previousElementSibling, blue.nextElementSibling을 해야 이전, 다음 요소 노드가 나옵니다.

  모든 노드 요소 노드만
부모 parentNode parentElement
자식 childNodes
firstChild
lastChild
children
firstElementChild
lastElementChild
형제 previousSibling
nextSibling
previousElementSibling
nextElementSibling





공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함