DOM 생동감 만들기: 동적 웹 페이지의 비밀

DOM 노드 생성하기

자바스크립트에서는 document.createElement와 document.createTextNode 메서드를 사용해 새로운 DOM 노드를 만들 수 있습니다.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>문서 수정 예제</title>
  <style>
    .notice {
      padding: 12px;
      margin: 10px 0;
      border: 1px solid #007700;
      background-color: #e0ffe0;
      font-family: sans-serif;
    }
  </style>
</head>
<body>
  <script>
    // 1) div 요소 생성하기
    const noticeBox = document.createElement('div');
    noticeBox.className = 'notice';

    // 2) 텍스트 노드 생성 후 요소에 추가하기
    const welcomeText = document.createTextNode('환영합니다! 오늘도 즐거운 하루 되세요.');
    noticeBox.appendChild(welcomeText);

    // 3) 생성된 노드를 문서에 삽입하기
    // body의 맨 위에 삽입
    document.body.prepend(noticeBox);
  </script>
</body>
</html>

노드 삽입 메서드

DOM 노드를 문서 내 원하는 위치에 삽입하는 데는 여러 메서드가 있습니다.

append() / prepend()

지정한 요소의 마지막 혹은 첫 번째 자식으로 삽입합니다.

before() / after()

지정한 요소의 바로 앞이나 뒤에 삽입합니다.

replaceWith()

지정한 요소를 새로운 노드로 대체합니다.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>노드 삽입 예제</title>
</head>
<body>
  <ul id="myList">
    <li>첫 번째 항목</li>
    <li>두 번째 항목</li>
    <li>세 번째 항목</li>
  </ul>

  <script>
    const list = document.getElementById('myList');

    // 목록의 맨 앞에 새로운 항목 삽입
    const newFirstItem = document.createElement('li');
    newFirstItem.textContent = '새로운 첫 항목';
    list.prepend(newFirstItem);

    // 목록의 맨 뒤에 새로운 항목 삽입
    const newLastItem = document.createElement('li');
    newLastItem.textContent = '새로운 마지막 항목';
    list.append(newLastItem);

    // 두 번째 항목 앞에 텍스트 노드와 구분선 삽입
    list.children[1].before('--- 구분선 ---', document.createElement('hr'));

    // 기존 항목을 새로운 항목으로 교체하기
    const replacement = document.createElement('li');
    replacement.textContent = '교체된 항목';
    list.children[3].replaceWith(replacement);
  </script>
</body>
</html>

노드 삭제와 복제

노드 삭제

요소를 삭제하려면 node.remove() 메서드를 사용하면 됩니다.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>노드 삭제 예제</title>
</head>
<body>
  <div id="tempMessage" style="padding: 10px; border: 1px solid #ccc;">
    잠시 후 이 메시지는 사라집니다.
  </div>

  <script>
    const tempMsg = document.getElementById('tempMessage');
    setTimeout(() => {
      tempMsg.remove();
      console.log("메시지가 삭제되었습니다.");
    }, 3000);
  </script>
</body>
</html>

노드 복제하기

이미 존재하는 노드를 복제할 때는 cloneNode(deep) 메서드를 사용합니다. 인수로 true를 전달하면 자식 노드까지 모두 복제되고, false이면 현재 노드만 복제됩니다.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>노드 복제 예제</title>
</head>
<body>
  <div id="sourceBox" style="padding: 15px; background: #f9f9f9;">
    <p><strong>중요:</strong> 이 박스는 복제될 예정입니다.</p>
  </div>

  <script>
    const sourceBox = document.getElementById('sourceBox');

    // sourceBox의 깊은 복제본 생성 (자식까지 모두 복제)
    const cloneBox = sourceBox.cloneNode(true);

    // 복제한 박스의 텍스트 변경
    cloneBox.querySelector('strong').textContent = '복제됨:';
    
    // 원본 박스 아래에 복제본 삽입
    sourceBox.after(cloneBox);
  </script>
</body>
</html>

DocumentFragment 활용하기

여러 노드를 한 번에 문서에 삽입해야 할 때, DocumentFragment를 사용하면 성능상의 이점을 누릴 수 있습니다. DocumentFragment는 가상의 컨테이너로, 여러 노드를 임시로 담은 후 한 번에 DOM에 추가할 수 있습니다.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>DocumentFragment 예제</title>
</head>
<body>
  <ul id="itemList"></ul>

  <script>
    function createListItems() {
      const fragment = document.createDocumentFragment();
      for (let i = 1; i <= 5; i++) {
        const li = document.createElement('li');
        li.textContent = `항목 ${i}`;
        fragment.appendChild(li);
      }
      return fragment;
    }

    const list = document.getElementById('itemList');
    list.appendChild(createListItems());
    // 한 번에 여러 li 요소가 추가됩니다.
  </script>
</body>
</html>

DocumentFragment를 사용하면 DOM에 직접 여러 번 접근하지 않고 한 번에 추가할 수 있으므로, 페이지의 성능을 최적화하는 데 도움이 됩니다.

구식 삽입·삭제 메서드 (Legacy Methods)

옛날 스크립트에서는 지금과 같이 append, prepend 등의 메서드 대신 아래와 같은 메서드들이 사용되었습니다:

  • appendChild(node)
  • insertBefore(newNode, referenceNode)
  • removeChild(node)
  • replaceChild(newNode, oldNode)

이들 메서드는 여전히 동작하지만, 최신 메서드들이 더 간결하고 직관적이므로 새로운 프로젝트에서는 최신 메서드를 사용하는 것이 좋습니다.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>구식 메서드 예제</title>
</head>
<body>
  <ul id="legacyList">
    <li>기존 항목 1</li>
    <li>기존 항목 2</li>
  </ul>

  <script>
    const list = document.getElementById('legacyList');

    // 새로운 항목을 만들어 마지막에 추가
    const newItem = document.createElement('li');
    newItem.textContent = '새 항목 (appendChild)';
    list.appendChild(newItem);

    // 두 번째 항목 앞에 항목 삽입
    const insertedItem = document.createElement('li');
    insertedItem.textContent = '삽입된 항목 (insertBefore)';
    list.insertBefore(insertedItem, list.children[1]);
  </script>
</body>
</html>