Daily Front_Minhhk

[JS] DOM과JS, createDocumentFragment(), node vs element, children과 childNodes의 차이, children과 childNodes의 차이, appendChild() 본문

Code개발일지

[JS] DOM과JS, createDocumentFragment(), node vs element, children과 childNodes의 차이, children과 childNodes의 차이, appendChild()

Minhhk 2022. 11. 10. 20:17

DOM은 플랫폼이나 구체적인 언어 구현에 종속된 것이 아닌 언어 독립적 인터페이스다. 반드시 자바스크립트로 구현할 필요 없이 DOM 인터페이스 구현만으로 DOM을 조작할 수 있다.

DOM 과 자바스크립트

문서(document) 와 문서의 요소(element) 에 접근하기 위해 DOM 이 사용된다. DOM 은 프로그래밍 언어는 아니지만 DOM 이 없다면 자바스크립트 언어는 웹 페이지 또는 XML 페이지 및 요소들과 관련된 모델이나 개념들에 대한 정보를 갖지 못하게 된다.

 

문서의 모든 element - 전체 문서, 헤드, 문서 안의 table, table header, table cell 안의 text - 는 문서를 위한 document object model 의 한 부분이다. 때문에, 이러한 요소들을 DOM 과 자바스크립트와 같은 스크립팅 언어를 통해 접근하고 조작할 수 있는 것이다.

초창기에는 자바스크립트와 DOM 가 밀접하게 연결되어 있었지만, 나중에는 각각 분리되어 발전해왔다.

 

페이지 콘텐츠(the page content)는 DOM 에 저장되고 자바스크립트를 통해 접근하거나 조작할 수 있다. 이것을 방정식으로 표현하면 아래와 같다:

API (web or XML page) = DOM + JS (scripting language)

 

DOM 은 프로그래밍 언어와 독립적으로 디자인되었다. 때문에 문서의 구조적인 표현은 단일 API 를 통해 이용가능하다. 이 문서에서는 자바스크립트를 주로 사용하였지만, DOM 의 구현은 어떠한 언어에서도 가능하다. 아래는 파이썬을 사용한 예제이다:


 

Document.createDocumentFragment()

오프스크린 DOM 트리를 빌드하기 위해 DOM 노드를 추가할 수 있는 새 빈 공간을 만듭니다 .

 

createDocumentFragment()

 


HTML <template> 태그

정의 및 특징

<template> 태그는 추가되거나 복사될 수 있는 HTML 요소들을 정의할 때 사용합니다.

<template> 요소 내의 콘텐츠는 페이지가 로드될 때 즉시 렌더링되지 않으며, 따라서 사용자에게는 보이지 않습니다. 하지만 나중에 자바스크립트를 사용하여, 해당 콘텐츠를 복제한 후 보이도록 렌더링할 수 있습니다.

<template> 요소는 특정 HTML 요소들을 원하지 않을 때까지 계속해서 다시 사용할 수 있게 해줍니다. 만약 <template> 요소를 사용하지 않고 이러한 작업을 수행하려면, 자바스크립트를 사용하여 브라우저가 해당 HTML 요소들을 렌더링하지 않도록 HTML 코드를 작성해야 합니다

 

 

  • element와 node의 차이를 이해할 수 있다.

node vs element

DOM 문서는 node의 계층 구조로 이루어져 있습니다.

이 node는 여러 가지 다양한 유형이 존재합니다. 요소(element), 텍스트, 주석 등등...

element는 이러한 node의 여러가지 유형 중 한 가지입니다.

위 그림과 같이 element는 여러 가지 node의 유형 중 한 타입입니다.

즉, node는 element의 상위 개념입니다.

좀 더 자세히 설명하면,

element는 html 문서에서 <div>, <p>, <title>과 같은 태그를 사용해서 작성된 node라고 할 수 있습니다.

1. node

node는

태그, 텍스트, 주석 등을 모두 포함

node의 유형은 Node.nodeType 속성을 이용하여 구분할 수 있다.

목록은??

  • Node.ELEMENT_NODE
  • Node.ATTRIBUTE_NODE
  • Node.TEXT_NODE
  • Node.CDATA_SECTION_NODE
  • Node.PROCESSING_INSTRUCTION_NODE
  • Node.COMMENT_NODE
  • Node.DOCUMENT_NODE
  • Node.DOCUMENT_TYPE_NODE
  • Node.DOCUMENT_FRAGMENT_NODE

2. element

  • element는 node의 한 종류
  • element는 <html>, <head>, <title>, <body>, <h2>, <p>, …
  • 주로, <p>, <div> 같은 태그를 사용해서 작성된 노드

  • children과 childNodes의 차이를 이해할 수 있다.
<div>
    <!-- 내용 시작 -->
    <p>은하수를 여행하는 히치하이커를 위한 안내서</p>
    <p>오리엔트 특급살인</p>
</div>

childNodes: 자식 노드에 접근

현재 요소의 자식 노드가 포함된 NodeList를 반환합니다. 이때 반환되는 NodeList에는 요소 노드뿐만 아니라 주석 노드와 같은 비 요소 노드를 포함합니다.

document.querySelector("div").childNodes

크롬 브라우저를 열고 콘솔 창에서 div 요소의 childNodes 프로퍼티를 확인해 봤습니다. 7개의 노드가 있는 노드 리스트가 나타납니다. 이중에 요소 노드는 2개입니다. 나머지는 주석과 줄 바꿈입니다.

children: 자식 요소에 접근

현재 요소의 자식 요소가 포함된 HTMLCollection을 반환합니다. 비 요소 노드는 모두 제외됩니다.

document.querySelector("div").children

요소 노드 이외의 노드가 필요하지 않은 경우라면 children 프로퍼티를 사용하면 되겠습니다.


  • children과 childNodes의 차이를 이해할 수 있다.

차이점 remove() removeChild()

인터넷 익스플로러 미지원 지원
부모 엘리먼트 불필요 필요
반환값 없음 삭제한  노드 참조 반환.
노드 리스트 삭제 미지원 미지원
하위 노드 삭제 지원 지원

remove() 는 노드를 메모리에서 삭제하고 종료합니다.

removeChild()는 노드를 삭제하는 것이 아닙니다.

쉽게 말해서

삭제할노드.remove()

삭제할노드의_부모노드.removeChild(삭제할노드)

이렇게 생각하실 수 있습니다.

메모리에 해당 노드는 그대로 존재하며, 부모 노드와의 부모-자식관계를 끊어 DOM 트리에서 해제하는 것입니다. 최종적으로는 관계를 끊은 해당 노드의 참조를 반환합니다.

반환값을 변수에 저장하지 않으면 삭제하는 노드의 참조가 더이상 없기 때문에, 자바스크립트 엔진의 GC(Garbage Collection)에 의해 잠시 후 메모리에서 삭제됩니다.

반환된 노드 참조를 변수에 담아 다른 DOM 위치에 붙일 수 있습니다.


<divclass="a">
    <span></span>
</div>
<div class="b"></div>

JavaScript로 appendChild 메소드를 사용하면,

const span = document.querySelector(‘span’);
const divB = document.querySelector(‘.b’);
divB.appendChild(span);

정답은 span이 new parent div B로 클론되지 않고 움직인다는 것이었습니다.

이 것은 appendChild method를 MDN에서 읽으면 알 수 있다고 합니다.

Node.appendChild()

Node.appendChild() 메소드는 한 노드를 특정 부모 노드의 자식 노드 리스트 중 마지막 자식으로 붙입니다. 만약 주어진 노드가 이미 문서에 존재하는 노드를 참조하고 있다면 appendChild() 메소드는 노드를 현재 위치에서 새로운 위치로 이동시킵니다. (문서에 존재하는 노드를 다른 곳으로 붙이기 전에 부모 노드로 부터 지워버릴 필요는 없습니다.)

이것은 한 노드가 문서상의 두 지점에 동시에 존재할 수 없다는 것을 의미합니다. 그래서 만약 노드가 이미 부모를 가지고 있다면 우선 삭제되고 새로운 위치로 이동합니다.

 

Node.cloneNode() 메소드는 노드가 새로운 부모의 밑으로 붙기 전에 노드를 복제합니다. cloneNode 메소드로 만들어진 복사된 노드들은 자동적으로 문서에 적용되지 않는다는 것에 주의하세요.

 

이 메소드는 서로 다른 문서로 노드를 이동시키진 못합니다.

만약 노드를 다른 문서로 이동시키고 싶다면

document.importNode()

메소드를 사용하셔야 합니다.


  • offsetTop 등을 이용하여 좌표 정보를 조회할 수 있다.

HTMLElement.offsetTop

읽기 전용 속성 은 가장 가까운 위치 에 **HTMLElement.offsetTop**있는 상위 요소의 상단 내부 경계를 기준으로 현재 요소의 외부 경계까지의 거리를 반환합니다

number //

const d = document.getElementById("div1");
const topPos = d.offsetTop;

if (topPos > 10) {
  // object offset is more
  // than 10 pixels from its parent
}

  • offsetWidth 등을 이용하여 크기 정보를 조회할 수 있다.

HTMLElement.offsetWidth

읽기 전용 속성 은 **HTMLElement.offsetWidth**요소의 레이아웃 너비를 정수로 반환합니다.

일반적으로 offsetWidth테두리, 패딩 및 세로 스크롤 막대(렌더링된 경우)를 포함하여 요소의 CSS 너비를 픽셀 단위로 측정합니다.

  • children과 childNodes의 차이를 이해할 수 있다.
<div>
    <!-- 내용 시작 -->
    <p>은하수를 여행하는 히치하이커를 위한 안내서</p>
    <p>오리엔트 특급살인</p>
</div>