티스토리 뷰

▶DOM Node 추가·제거

DOM API를 사용해 동적으로 기존 노드의 위치를 바꾸거나, 노드를 추가하고, 제거하는 방법에 대해 알아보겠습니다.

 

1) createElement

document.createElement(tagName)을 호출하면 tagName에 맞는 요소 노드를 생성합니다.

const divElem = document,createElement('div'); // <div></div>
const liElem = document.createElement('li'); // <li></li>

liElem.className = 'li-class-name'; // class 속성 할당
liElem.id = 'li-id'; // id 속성 할당
liElem.innerHTML = "<strong>삽입되는 요소</strong>"; // li 내부 HTML 노드 할당

 

2) appendChild(), insertBefore()

이 메서드들을 이용해 노드를 이동하거나 새로운 노드를 추가할 수 있습니다.

appendChild()는 부모 노드의 마지막에 자식 노드를 추가하는 메서드이며, insertBefore()는 부모의 특정 노드 앞에 노드를 삽입하는 메서드입니다.

각각의 동작은 다음을 보면 쉽게 이해할 수 있습니다.

insertBefore(), appendChild()의 노드 추가 위치

appendChild()와 insertBefore() 메서드 모두 새로 생성한 노드뿐만 아니라 기존 노드의 위치도 이동시킬 수 있습니다.

<body>
    <div>
        <h1>리스트 시작</h1>
        <ol id="ol-id">
            <li id="first-li-id">1</li>
            <li>2</li>
        </ol>
    </div>
</body>

<script>
    const divElem = document.createElement("div");
    const liElem = document.createElement("li");

    liElem.className = "li-class-name";
    liElem.id = "li-id";
    liElem.innerHTML = "<strong>삽입되는 요소</strong>";

    // 이전 예제 코드에 이어서
    const olElem = document.getElementById("ol-id");

    olElem.appendChild(liElem); // createElement로 생성한 요소 삽입

    const firstLiElem = document.getElementById("first-li-id");
    olElem.appendChild(firstLiElem); // 기본 요소 삽입
</script>

예제 실행 결과(첫 번째 항목 1이 마지막으로 이동)

HTML로 작성한 코드대로라면

---------------------------

리스트 시작

1. 1

2. 2

---------------------------

가 됩니다.

그런데 <script> 부분에서 우선 <div>와 <li>를 만들어주었습니다.

그 후에 <li>인 liElem 객체로 innerHTML = "<strong>삽입되는 요소</strong>"를 저장했습니다.

(참고로 <strong>은 강조 태그의 한 종류로 볼드체로 입력하게 해줍니다.)

이제 기존 노드에서 liElem를 appendChild해주기 때문에 가장 마지막 자식 노드로 들어가게 됩니다.

---------------------------

리스트 시작

1. 1

2. 2

3. 삽입되는 요소

---------------------------

마지막으로 getElementById를 통해 HTML에서 id="first-li-id"를 찾아 fisrtLiElem 객체를 저장합니다.

이제 firstLiElem를 appendChild 해주어 가장 마지막 자식 노드로 들어가게 됩니다.

---------------------------

리스트 시작

1. 2

2. 삽입되는 요소

3. 1

---------------------------

 

insertBefore()의 경우 parentNode.insertBefore(삽입하는 노드, 참조 노드) 형태로 사용할 수 있으며 참조 노드의 앞으로 이동합니다.

참조 노드가 null일 경우에는 appendChild()와 동일하게 작동합니다.

<body>
    <div>
        <h1>리스트 시작</h1>
        <ol id="ol-id">
            <li id="first-li-id">1</li>
            <li>2</li>
        </ol>
    </div>
</body>

<script>
    const divElem = document.createElement("div");
    const liElem = document.createElement("li");

    liElem.className = "li-class-name";
    liElem.id = "li-id";
    liElem.innerHTML = "<strong>삽입되는 요소</strong>";

    // 이전 예제 코드에 이어서
    const olElem = document.getElementById("ol-id");
    const firstLiElem = document.getElementById("first-li-id");

   olElem.insertBefore(liElem, firstLiElem);
</script>

예제 실행 결과(첫 번째 항목으로 새로운 요소 삽입)

 

3) append(), prepend(), after(), before()

appendChild()와 insertBefore() 외에도 노드를 이동하거나 새로운 노드를 추가할 수 있는 다양한 메서드들이 있습니다.

  • prepend() :  요소 내부의 가장 앞으로 이동
  • append() : 요소 내부의 마지막으로 이동
  • before() : 요소 앞으로 이동
  • after() : 요소 뒤로 이동

각각의 동작은 다음 그림을 보면 쉽게 이해할 수 있습니다.

prepend(), append(), before(), after()의 노드 추가 위치

이 메서드들은 문서에 나타내기 위해 어디에 삽입할지 명시해야 합니다.

<body>
    <div>
        <h1>리스트 시작</h1>
        <ol id="ol-id">
            <li>1</li>
            <li>2</li>
        </ol>
    </div>
</body>

<script>
    const liElem = document.createElement('li');
    liElem.id = 'li-id';
    liElem.innerHTML = "<strong>삽입되는 요소</strong>";

    const orderdListElem = document.getElementById('ol-id');

    orderdListElem.append(liElem); // 리스트의 가장 마지막 위치에 삽입되어 번호는 3이 매겨집니다.
</script>

예제 코드의 결과로 다음 그림처럼 리스트 마지막에 추가됩니다.

예제 실행 결과(마지막 항목으로 새로운 요소 삽입)

또한 append()prepend() 메서드는 문자열(DOMString)을 인자로 받을 경우 자동으로 텍스트 노드를 생성하여 삽입합니다.

// 직전 예제 코드에 이어서...
orderedListElem.prepend('텍스트 삽입');
// 리스트 가장 앞으로 텍스트 노드가 생성되어 삽입됩니다.

예제 코드의 실행 결과는 다음과 같습니다.

예제 실행 결과(첫 번째 항목으로 텍스트 노드 삽입)

after()와 before() 또한 append(), prepend()와 동일한 사용법을 가지며 이동시키고 싶은 위치에 따라 메서드를 선택해 사용합니다.

 

4) append() vs appendChild()

appendChild(), insertBefore()가 이미 존재함에도 불구하고 새롭게 append(), prepend(), after(), before()가 등장한 이유는 무엇일까여?

  • append()와 appendChild()를 대표로 두 그룹의 차이점을 비교해 보겠습니다.앞서 언급했듯이 append()의 경우 Node 객체뿐만 아니라 문자열을 인자로 넘길 수 있습니다. append()에 문자열 인자를 넘겨줄 경우, 자동으로 텍스트 노드를 생성해 삽입해 줍니다. 하지만 appendChild()는 문자열을 인자로 넘겨줄 경우 에러가 발생합니다.
const bodyElem = document.querySelector('body');
const divElem = document.createElement('div');
const str = 'Hello world';

bodyElem.append(divElem); // 가능
bodyElem.appendChild(divElem); // 가능

bodyElem.append(str); // 가능
bodyElem.appendChild(str); // error
  • append()의 경우 여러 노드를 한 번에 추가할 수 있습니다. 하지만 appendChild()는 여러 노드를 추가하고 싶을 경우 메서드를 여러 번 호출해야 합니다.
const bodyElem = document.querySelector('body');
const elem1 = document.createElement('div');
const elem2 = document.createElement('div');

bodyElem.append(elem1, elem2); // 두 노드 모두 순서대로 추가
bodyElem.appendChild(elem1, elem2); // 첫 번째 노드만 추가됨. 나머지 노드는 무시됩니다.

이런 특성 외에 더 유연하고 일관된 사용법을 제공항며 직관적이기 때문에 appendChild()보다 append()의 사용을 더 권장하고 있습니다.

하지만 append()는 IE 브라우저에서 지원되지 않습니다.

그렇기 때문에 저사양의 IE 브라우저를 지원해야 한다면 appendChild()를 사용해야 합니다.

(appendChild()는 IE6 부터 지원합니다.)

 

5) removeChild()

DOM 트리 내에 노드를 제거할 때 사용합니다.

제거하고자 하는 노드가 존재할 경우 부모 노드에서 removeChild() 메서드를 호출해 제거합니다.

<div id='div-id'>id가 div-id인 요소</div>

<script>
	const divElem = document.getElementById('div-id'); // id가 div-id인 요소 선택

	setTimeout(() => {
		divElem.parentNode.remove(divElem); // 자식 요소 삭제
	}, 1000);
</script>

 

6) remove()

removeChild()와 비슷하게 DOM 트리 내에서 노드를 제거하고 싶을 경우 node.remove()를 이용합니다.

remove() 메서드는 제거하고 싶은 노드에서 직접 메서드를 호출할 수 있기 때문에 removeChild()보다 더 간결하게 작성할 수 있습니다.

하지만 이 메서드 또한 IE에서 지원하지 않으므로 IE를 사용하는 경우 removeChild()를 사용해야 합니다.

<div id='div-id'>id가 div-id인 요소</div>

<script>
	const divElem = document.getElementById('div-id'); // id가 div-id인 요소 선택

	setTimeout(() => {
		divElem.remove(); // 요소 삭제
	}, 1000);
</script>

 

7) insertAdjacentHTML()

XML또는 HTML로 해석될 수 있는 문자열을 파싱한 뒤 적절한 노드를 생성해 특정 위치에 삽입합니다.

elem.insertAjacentHTML('beforebegin', '<span>Hello world!</span>');

지정할 수 있는 위치는 beforebegin, afterbegin, beforeend, afterend 4가지입니다.

beforebegin은 요소의 앞에,

afterbegin은 요소 안 첫 번째 자식 요소로,

beforeend는 요소 안 마지막 자식 요소로,

afterend는 요소의 바로 뒤에 삽입됩니다.

각 인자에 따라 추가되는 노드의 위치는 다음 그림과 같습니다.

beforeend, afterbegin, beforeend, afterend 인자에 따른 노드 추가 위치

innerHTML과 이름, 역할이 비슷하게 느껴질 수 있습니다.

하지만 구체적인 동작에서 차이점을 갖게 되는데 innerHTML을 사용한다면 이미 사용 중인 요소를 전부 없애고 다시 파싱을 하게 됩니다.

innerAdjacentHTML()은 이미 사용 중인 요소는 파싱하지 않고 새로 추가되는 노드만 작업합니다.

이런 특성 때문에 innerAdjacentHTML()은 innerHTML에 비해 성능상 이점을 갖습니다.

 


여기까지 DOM 노드 추가 및 삭제에 대해 알아보았습니다 :)

728x90
LIST

'프론트엔드 > DOM' 카테고리의 다른 글

[DOM] ⑤ DOM 이벤트  (0) 2022.07.29
[DOM] ④ DOM 요소 검색하기  (0) 2022.07.27
[DOM] ② DOM Node  (0) 2022.07.26
[DOM] ① DOM 트리  (0) 2022.07.25
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
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
글 보관함