본문 바로가기
프론트엔드/javascript

노드 동적 생성과 DocumentFragment

by 느바 2022. 2. 3.
반응형

노드 동적 생성과 DocumentFragment

 

DocumentFragment 노드는 문서, 요소, 어트리뷰트, 텍스트 노드와 같은 노드 객체의 일종으로,

부모 노드가 없어서 기존 DOM과는 별도로 존재한다는 특징이 있다.

DocumentFragment 노드는 컨테이너 요소와 같이 자식 노드들의 부모 노드로서 별도의 서브 DOM을 구성하여 기존 DOM에 추가하기 위한 용도로 사용한다.

DocumentFragment는 활성화된 문서 트리 구조의 일부가 아니기 때문에 fragment를 변경해도 문서에는 영향을 미치지 않으며(reflow 포함) 성능에도 영향이 없다.

 

https://developer.mozilla.org/ko/docs/Web/API/DocumentFragment

 

DocumentFragment - Web API | MDN

DocumentFragment 인터페이스는 부모가 없는 아주 작은 document 객체를 나타냅니다. Document의 경량화된 버전으로 사용되며 표준문서와 같이 노드로 구성된 문서 구조의 일부를 저장합니다.

developer.mozilla.org

https://developer.mozilla.org/ko/docs/Web/API/Document/createDocumentFragment

 

Document.createDocumentFragment() - Web API | MDN

새로운 빈 DocumentFragment 를 생성합니다.

developer.mozilla.org

 

다음은, fruits ul 요소에 동적으로 apple, banana, orange li 요소를 생성하여 추가하는 예제이다.

 

① div 컨테이너 요소에 세 개의 li 요소를 생성하여 추가한 다음, 이 div를 fruits에 추가하는 방법

div라는 컨테이너 요소를 fruits 요소에 자식으로 추가할 때 DOM은 한 번만 변경된다.

그러나, 불필요한 컨테이너 요소가 추가되어 바람직하지 않다.

<!DOCTYPE html>
<html>
    <body>
        <ul id="fruits">
        </ul>
        <script>
            const $fruits = document.getElementById('fruits');

            // 컨테이너 요소 노드 생성
            const $container = document.createElement('div');

            ['apple','banana','orange'].forEach(text => {
                // 1. 요소 노드 생성
                const $li = document.createElement('li');

                // 2. 텍스트 노드 생성
                const textNode = document.createTextNode(text);

                // 3. 텍스트 노드를 $li 요소 노드의 자식 노드로 추가
                $li.appendChild(textNode);

                // 4. $li 요소 노드를 컨테이너 요소의 마지막 자식 노드로 추가
                $container.appendChild($li);
            });
            //5. 컨테이너 요소 노드를 #fruits 요소 노드의 마지막 자식 노드로 추가
            $fruits.appendChild($container);
        </script>
    </body>    
</html>

② DocumentFragment 노드에 세 개의 li 요소를 생성하여 추가한 다음, 이 노드를 fruits에 추가하는 방법

DocumentFragment 노드는 기존 DOM과는 별도로 존재하므로 DocumentFragment 노드에 자식 노드를 추가하여도 기존 DOM에는 어떠한 변경도 발생하지 않는다.

또한, DocumentFragment 노드를 DOM에 추가하면 자신은 제거되고 자신의 자식 노드만 DOM에 추가된다.

<!DOCTYPE html>
<html>
    <body>
        <ul id="fruits">
        </ul>
        <script>
            const $fruits = document.getElementById('fruits');

            // DocumentFragment 노드 생성
            const $fragment = document.createDocumentFragment();

            ['apple','banana','orange'].forEach(text => {
                // 1. 요소 노드 생성
                const $li = document.createElement('li');

                // 2. 텍스트 노드 생성
                const textNode = document.createTextNode(text);

                // 3. 텍스트 노드를 $li 요소 노드의 자식 노드로 추가
                $li.appendChild(textNode);

                // 4. $li 요소 노드를 DocumentFragment 노드의 마지막 자식 노드로 추가
                $fragment.appendChild($li);
            });
            //5. DocumentFragment 노드를 #fruits 요소 노드의 마지막 자식 노드로 추가
            $fruits.appendChild($fragment);
        </script>
    </body>    
</html>

 

반응형