Web/JS

[Web/JS] 자바스크립트 - DOM에서의 노드 추가 및 삭제

poopooreum 2024. 5. 16. 21:19
반응형

✏️ 노드 리스트

DOM에 접근할 때 querySelectorAll() 메서드를 사용하면 노드를 한꺼번에 여러 개 가져올 수 있습니다. 이때 노드 정보를 여러 개 저장한 것을 노드 리스트라고 하고 배열과 비슷하게 동작할 수 있습니다. 예제를 통해서 접근해보겠습니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <title>Web Programming</title>
    <link rel="stylesheet" href="css/nodelist.css">
</head>
<body>
  <h1>Web Programming</h1>
  <ul id="itemList">
    <li>HTML</li>
    <li>CSS</li>
    <li>Javascript</li>
  </ul>
</body>
</html>

위의 코드를 실행한 후 F12 키를 눌러서 콘솔 창에 document.querySelectorAll("li")를 입력한 모습입니다. querySelectorAll()은 노드 리스트를 반환하기 때문에 화면 출력 결과에서 Nodelist(3) [li, li, li]가 출력되었습니다. 이렇게 입력을 하면 노드 리스트뿐만 아니라 인덱스와 요솟값이 저장되고 length 속성에서 몇 개의 노드가 저장되어 있는지 알 수 있습니다. 또한 노드 리스트는 배열처럼 특정 인덱스로 접근할 수 있습니다.

✏️ 새로운 노드 추가하기

노드를 추가하기 전에 DOM 트리를 구성하는 기본 원칙을 한 번더 상기시켜보겠습니다.

  1. 모든 HTML 태그는 요소(element) 노드입니다.
  2. HTML 태그에서 사용하는 텍스트 내용은 자식 노드인 텍스트(text) 노드입니다.
  3. HTML 태그에 있는 속성은 자식 노드인 속성(attribute) 노드입니다.
  4. 주석은 주석(comment) 노드입니다.

이 원칙에 따라 어떠한 태그를 노드로 추가한다면 단순히 태그에 해당하는 요소 노드뿐안 아니라 텍스트 노드와 속성 노드도 추가해야합니다. 즉 새로운 노드를 추가할 때는 웹 문서에 어떤 소스를 추가할지 먼저 생각하고, 그에 따라 요소 노드나 텍스트, 속성 노드 등을 만들어야 합니다.

 

✏️ 텍스트 노드를 사용하는 새로운 요소 추가하기

#1 요소 노드 만들기 - createElement() 메서드

요소 노드는 createElement() 메서드를 사용하여 괄호 안에 해당하는 요소 노드를 만들 수 있습니다. 

기본형 => document.createElement(노드명)

var newP = document.createElement("p")

// 이렇게 생성을 하게 되면 새로운 노드만 만들었을 뿐이지 아직 웹 문서에 새로운 노드를 추가한 것이 아닙니다. 코드에서 p 요소를 만들었으므로 <p> 태그의 내용에 해당하는 텍스트 노드를 만들어야 합니다.

 

현재까지의 p노드를 추가한 DOM 트리의 모습입니다.

#2 텍스트 노드 만들기 - createTextNode() 메서드

새로운 요소 노드를 만들었다면 내용을 담는 텍스트 노드를 자식 노드로 만들어 연결시켜주어야 합니다.

기본형 => document.createTextNode(텍스트);

var txtNode = document.createTextNode("DOM은 document object Model의 줄임말");

// 위에서 만들었던 p요소에 담을 내용이 있는 텍스트 노드를 txtNode 변수로 저장하겠습니다.

 

텍스트 노드를 만든 현재까지의 DOM 트리의 모습입니다.

#3 자식 노드 연결하기 - appendChild() 메서드

현재까지 새로운 p노드(newP)와 사용할 텍스트 노드(txtNode)를 만들었습니다. 이제는 이 두개의 노드를 연결시켜주어야 할 차례입니다. 이때 appendChild() 메서드를 사용해서 두 개의 노드를 연결시킬 수 있습니다. 이때, 연결하는 자식 노드는 부모 노드의 자식 노드 중에서 가장 맨 끝에 추가됩니다.

기본형 => 부모노드.appendChild(자식 노드)

newP.appendChild(txtNode);
document.getElementById("info").appendChild(newP);

// 텍스트 노드 txtNode를 요소 노드 newP의 자식 노드로 연결하고, newP 노드를 다시 <div id = "info"></div>의 자식 노드로 연결해주겠습니다.

부모 노드와 자식 노드들을 연결해준 DOM 트리의 모습입니다.

#4 전체 소스 코드 완성하기

더 보기 버튼을 누르면 노드를 연결해주도록 해주는 예제입니다.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>DOM</title>
  <style>
    #container{
      width:500px;
      margin:10px auto;
      padding:20px;
    }
    #info {
      margin-top:20px;
    }
  </style>
</head>
<body>
  <div id="container">    
    <h1>DOM을 공부합시다</h1>
    <a href="#" onclick="addP(); this.onclick='';">더 보기</a>    
    <div id="info"></div>
  </div>
  <script>
    function addP() {
      var newP = document.createElement("p");
      var txtNode = document.createTextNode("DOM은 Document Object Model의 줄임말입니다.");
      newP.appendChild(txtNode);
      document.getElementById("info").appendChild(newP);
    }
  </script>
</body>
</html>

 

 

✏️ 속성값이 있는 새로운 요소 추가하기

1. 요소 노드 만들기 - createElement() 메서드

위에서 했던 것처럼 createElement() 메서드를 사용해서 새로운 이미지 노드를 만들어보겠습니다.

var newImg = document.createElement("img");

 

#2 속성 노드 만들기 - createAttribute() 메서드

img 요소는 src 속성을 사용해서 이미지 파일의 경로를 지정해야 브라우저에 이미지를 보여줄 수 있기 때문에 createAttribute() 메서드를 사용해서 속성 노드를 만들어 주어야 합니다. 이미지 파일의 경로를 지정할 src와 대체 텍스를 지정할 alt를 위해 속성 노드를 추가하겠습니다. 

var srcNode = document.createAttribute("src");
var altNode = document.createAttribute("alt");
srcNode.value = "images/dom.jpg";
altNode.value - "돔 트리 예제 이미지";

 

#3 속성 노드 연결하기 - setAttributeNode() 메서드

텍스트 노드를 연결할 때 부모 노드와 자식 노드를 연결한 것처럼 속성 노드는 요소 노드의 자식으로 연결해 주어야 합니다. setAttributeNode() 메서드를 이용해서 새로 만든 속성 노드를 요소 노드에 추가할 수 있습니다. 만약 추가할 속성이 요소 노드에 이미 들어 있다면 기존 속성 노드로 대체합니다. newImg라는 새 요소를 만들고 srcNode라는 속성 노드를 추가하겠습니다.

newImg.setAttributeNode(srcNode);

 

4. 자식 노드 연결하기 - appendChild() 메서드

속성 노드끼리는 연결했지만 아직 img 요소는 만들어 놓기만 한 상태입니다. img 요소를 화면에 표시하기 위해서는 웹 문서의 DOM에 추가해야 하므로 appendChild() 메서드를 이용해서 연결해야 합니다. #info 위치에 새로 만든 img 요소를 자식 요소로 추가하겠습니다.

document.getElementById("info").appendChild(newImg);

 

#5. 전체 소스 코드 완성하기 

// <a> 태그에 있는 더 보기 링크를 클릭하면 <p> 태그를 사용한 텍스트와 images/dom.jpg이미지를 표시하는 예제입니다.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>DOM</title>
  <style>
    #container{
      width:500px;
      margin:10px auto;
      padding:20px;
    }
    #info {
      margin-top:20px;
    }
  </style>
</head>
<body>
  <div id="container">    
    <h1>DOM을 공부합시다</h1>
    <a href="#" onclick="addContents(); this.onclick='';">더 보기</a>    
    <div id="info"></div>
  </div>
  <script>
    function addContents() {
      var newP = document.createElement("p");
      var txtNode = document.createTextNode("DOM은 Document Object Model의 줄임말입니다.");
      newP.appendChild(txtNode);
      
      var newImg = document.createElement("img");
      var srcNode = document.createAttribute("src");
      var altNode = document.createAttribute("alt");
      srcNode.value = "images/dom.jpg";
      altNode.value = "돔 트리 예제 이미지";
      newImg.setAttributeNode(srcNode);
      newImg.setAttributeNode(altNode);

      document.getElementById("info").appendChild(newP);
      document.getElementById("info").appendChild(newImg);
    }
  </script>
</body>
</html>

 

✏️ 노드 삭제하기

위에서는 노드를 추가하고 연결하는 것을 알아봤다면 이번에는 DOM 트리에서 특정 노드를 삭제하는 방법을 알아보겠습니다. 노드를 삭제할 때 중요한 점은 부모 노드에서 자식 노드를 삭제해야 한다는 점입니다. 이 말은 삭제하는 노드가 있다면 반드시 부모 노드를 먼저 찾아야 한다는 말입니다. 그래서 노드를 삭제하는 메서드 위에 부모 노드를 찾아주는 프로퍼티가 필요합니다.

 

#1. parentNode 프로퍼티

이 프로퍼티는 현재 노드의 부모 노드에 접근해서 부모 노드의 요소를 반환해줍니다.

기본형 => 노드.parentNode

parentNode가 어떻게 반환되는지 알아볼 수 있는 사진입니다.

 

 

#2. removeChild() 메서드

부모 노드를 찾았다면 이제는 removeChild() 메서드를 이용해서 자식 노드를 삭제할 차례입니다.

기본형 => 부모노드.removeChild(자식노드)

// 예를 들어 li 노드를 삭제하려면 li의 부모 노드에서 삭제해야 합니다. 

li.parentNode.removeChild(li);

 

반응형