FE/JavaScript

[JS] DOM (3) - DOM 조작

mandelina 2022. 5. 18. 21:19

DOM 조작

- DOM조작이란 새로운 노드를 생성하여 DOM에 추가하거나, 기존 노드를 삭제 또는 교체하는것을 말한다.

- 성능에 영향을 주므로 최적화를 위해 주의하여 다뤄야한다.

 

 


 

innerHTML

- 요소내에 포함된 HTML마크업을 가져오거나 설정

- 렌더링된 콘텐츠를 표현

 

 

[단점]

- 그대로 innerHTML 프로퍼티에 할당하는것은 XSS에 취약하므로 위험하다.

- 또한 HTML마크업 문자열을 할당하는 경우 , 요소노드의 모든 자식노드를 제거하고 할당한 HTML 마크업 문자열을 파싱한다.

- 새로운 요소를 삽입할때 위치를 지정할 수 없다.

 

 


 

insertAdjacentHTML

- 요소노드를 주어진 위치에 배치

 

const sayHi = document.querySelector('.sayHi');
sayHi.insertAdjacentHTML('beforebegin', '<span>하나</span>');
sayHi.insertAdjacentHTML('afterbegin', '<span>둘</span>');
sayHi.insertAdjacentHTML('beforeend', '<span>셋</span>');
sayHi.insertAdjacentHTML('afterend', '<span>넷</span>');

위의 코드와 같이 첫번째 인수를 지정해서 사용하면 된다.

 

지정할 수 있는 인수는 1. beforebegin 2. afterbegin 3.beforeend 4.afterend 이다.

 

 

 


 

노드 추가 및 생성

 

요소 노드를 생성

 

const li = document.createElement('li');

위의 코드는 li노드를 생성하는 코드이다.

생성된 요소 노드는 기존  DOM에 추가되지 않고 홀로 존재하는 상태이다.

 

 

텍스트 노드를 생성 

const textNode = document.createText("안녕?");

 

텍스트 노드를 요소 노드의 자식으로 추가

li.appendChild(textNode);

그러면 현자 li와 '안녕?' 이라는 텍스트는 부자관계로 연결만 되어있는 상태이다.

 

 

한번에 쓰기

li.appendChild(document.createTextNode('안녕?'))

단 이경우는 요소노드의 자식노드가 있는 채로 할당하면 요소노드의 모든 자식은 제거되고 할당된 텍스트가 추가되므로 주의해야한다.

 

 

요소노드를 DOM에 추가

<!DOCTYPE html>
<html lang="ko">
<head>
</head>
<body>
  <ul id = "hello">
  //여기다 추가 할거임
  </ul>
</body>
</html>

[JS]

hello.appendChild(li)

이렇게 하면 hello 요소 노드의자식 요소로 추가된다.

 

 


 

복수 노드 생성 및 추가

 

여러 개의 요소노드를 생성하여 DOM에 추가하기

<!DOCTYPE html>
<html lang="ko">
  <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> </title>
  </head>
  <body>
    <ul class="num"></ul>

    <script>
      const num = document.querySelector(".num");

      ["one", "two", "three"].forEach((text) => {
        const li = document.createElement("li"); //요소 노드 생성
        const textNode = document.createTextNode(text); //textnode생성
        li.appendChild(textNode); //텍스트 노드를 자식노드로 넣기
        num.appendChild(li); //ul에 자식노드로 li넣기
      });
    </script>
  </body>
</html>

위코드에선 1. 3개요소노드 생성, 2. DOM에 3번 추가  즉, DOM 이 3번 변경된다.

 

리플로우, 리페인트 3번실행

 

 

 

Q. 리플로우,리페인트에 대해 알고싶다면?

https://mandelina-code.tistory.com/63

 

[FE] 웹페이지 렌더링과 page reflow & repaint

웹 페이지 렌더링 - 브라우저가 HTML파일을 화면에 그려내는 과정 1. 파싱 : HTML파일을 DOM으로 변환 (파싱) 2. 스타일 계산 : CSS를 CSSOM으로 파싱 3. 레이아웃 : CSSOM 정보를 토대로 레이아웃 트리(렌더

mandelina-code.tistory.com

 

 

Document.Fragment 사용

 

- 전 예제에서 보았던  DOM이 자주 변경되는 문제Document.Fragment노드를 통해 해결

- Document.Fragment는 별도 서브 DOM을 구성하여 기존 DOM에 추가하기 위한 용도로 사용

- 따라서 Document.Fragment 노드에 자식노드를 추가해도 기존 DOM은 변경사항 X

 

<!DOCTYPE html>
<html lang="ko">
  <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> </title>
  </head>
  <body>
    <ul class="num"></ul>

    <script>
      const num = document.querySelector(".num");
      const fragment = document.createDocumentFragment(); //fragment생성

      ["one", "two", "three"].forEach((text) => {
        const li = document.createElement("li"); 
        const textNode = document.createTextNode(text);
        li.appendChild(textNode); 
        fragment.appendChild(li); //  fragment에 자식노드로 li넣기
      });
      num.appendChild(fragment); // 기존 DOM에 추가
    </script>
  </body>
</html>

 

이렇게 하면 DOM변경은 1번 일어나며,  리플로우와 리페인트도 한번 실행

 

따라서 여러 요소노드를 DOM에 추가하는 경우  Document.Fragment 노드를 사용하는것이 효율적

 

 

 

 


 

노드 삽입

 

1. 마지막 노드로 추가

- Node.prototype.appendChild 사용

- 인수로 전달받은 노드를 자신이 호출한 노드의 마지막 자식요소 DOM에 추가

 

 

2. 지정된 위치에 노드 삽입

- Node.prototype.insertBefore(넣을노드,기준노드)

- 기준노드의 앞에 삽입한다.

- 두번째 인수의 노드는 반드시 insertBefore를 호출한 노드의 자식노드여야한다.

 

num.insertBefore(li,num.lastElementChild);

 


 

노드변경

 

노드이동

- 이미 존재하는 노드를 appendChild 또는 insertBefore 메서드 사용하여 DOM에 다시 추가

- 현재위치에서 노드를 제거하고 새로운 위치에 노드가 추가된다.

 

<!DOCTYPE html>
<html lang="ko">
  <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></title>
  </head>
  <body>
    <ul class="num">
      <li>one</li>
      <li>two</li>
      <li>three</li>
    </ul>
    <script>
      const $num = document.querySelector(".num");
      const [$one, $two] = $num.children;
      $num.appendChild($one); //one이 마지막 위치로이동
      $num.insertBefore($two, lastElementChild); //마지막요소 (three)기준 앞으로 이동
    </script>
  </body>
</html>

 

결과는 two - three - one이다.

 

 

 

노드복사

- Node.prototype.cloneNode 이용

- 노드의 사본을 생성하여 반환

- 매개변수 deep에 인수를 전달할 때  true -깊은복사 ,  false나 생략 : 얕은복사

- 얕은복사로 생성된 요소노드는 자손노드를 복사 x  따라서 텍스트노드는 없다.

 

const  $deepClone = $num.cloneNode (true); //깊은복사
const  $shallowClone = $num.cloneNode (false);  //얕은복사

 

노드교체

 

- Node.prototype.replaceChild (새노드,교체할 노드)

- 자신을 호출한 노드의 자식노드를 다른 노드로 교체

- 교체할 노드는 DOM에서 제거된다. 

 

num.replaceChild(newchild,$num.firstElementChild);

- num요소 노드의 첫 번째 자식 요소를 $newChild 요소 노드로 교체

 

 

노드삭제

- Node.prototype.removeChild(삭제할노드) 사용

- 삭제할 노드는 메서드를 호출한 자식 노드여야한다. 

 

 

$num.removeChild($num.lastElementChild)

- num요소노드의  마지막요소를 DOM에서 삭제

 

 


 

 

 

 

DOM(4) 에선  attribute 조작 및 style조작에 대해 알아보겠다.

 

 

https://mandelina-code.tistory.com/58

 

[JS] DOM (1) - DOM이란?

DOM이란? - HTML 문서의 계층적 구조와 정보를 표현하며, 이를 제어할 수 있는 API (프로퍼티,메소드)를 제공하는 트리자료구조이다. - 이때 각각의 요소와 속성, 콘텐츠를 표현하는 단위를 "노드 (nod

mandelina-code.tistory.com

https://mandelina-code.tistory.com/59

 

[JS] DOM (2) - 노드 탐색 , 및 Text 조작

노드탐색 - 요소노드를 얻고, DOM트리의 노드를 옮겨다니며 탐색할 경우가 있다. - 노드탐색 프로퍼티는 모두 자체적으로 값을 갖진 않고 다른 데이터 프로퍼티 값을 읽거나 저장할 때 호출되는

mandelina-code.tistory.com

https://mandelina-code.tistory.com/62

 

[JS] DOM (3) - DOM 조작

DOM 조작 - DOM조작이란 새로운 노드를 생성하여 DOM에 추가하거나, 기존 노드를 삭제 또는 교체하는것을 말한다. - 성능에 영향을 주므로 최적화를 위해 주의하여 다뤄야한다. innerHTML - 요소

mandelina-code.tistory.com

https://mandelina-code.tistory.com/66

 

DOM(4) - attribute 조작 및 style조작

 Attribute? - HTML 요소의 동작을 제어하기 위한 추가적인 정보를 제공한다. - 글로벌 어트리뷰트 :id , class ,style ,title ,lang ,hidden 등 - HTML 문서가 파싱될때 , 어트리뷰트 하나당 하나의 노드가 생성..

mandelina-code.tistory.com

 

'FE > JavaScript' 카테고리의 다른 글

DOM(4) - attribute 조작 및 style조작  (0) 2022.05.22
[JS] 이벤트 위임  (0) 2022.05.22
[JS] DOM (2) - 노드 탐색 , 및 Text 조작  (0) 2022.05.18
[JS] DOM (1) - DOM이란?  (0) 2022.05.17
[JS] JSON  (0) 2022.05.16