본문 바로가기

JS

JS - 점검 4 ( Document Object Model )

브라우저에 띄울 웹 페이지가 단순히 정보 전달만을 목적으로 하는 정적인 웹이라면 HTML, CSS로도 충분하겠지만 그 이상의 인터랙티브한 기능을 구현하고자 한다면 자바스크립트와 DOM을 반드시 사용해야 한다.

 

 

1. DOM 이란 무엇일까? (문서 객체 모델)

문서 객체 모델, 즉 DOM은 웹 페이지(HTML이나 XML 문서)의 콘텐츠 및 구조, 그리고 스타일 요소를 구조화 시켜 표현하여 프로그래밍 언어가 해당 문서에 접근하여 읽고 조작할 수 있도록 API를 제공하는 일종의 인터페이스이다. 즉 자바스크립트 같은 스크립팅 언어가 쉽게 웹 페이지에 접근하여 조작할 수 있게끔 연결시켜주는 역할을 담당한다.

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Document</title>
	</head>
	<body>
		<h2>HTML 웹 페이지 문서 입니다</h2>
	</body>
</html>

위의 HTML 코드를 기반으로 웹 페이지가 로드되면, 브라우저는 다음과 같이 여러 객체들을 생성이 된다.

 

 

window
└── document
    ├── head
    │   ├── meta (charset="UTF-8")
    │   ├── meta (name="viewport", content="width=device-width, initial-scale=1.0")
    │   └── title
    │       └── #text ("Document")
    └── body
        └── h2
            └── #text ("HTML 웹 페이지 문서 입니다")

주의 : window 객체는 브라우저의 창이나 프레임을 추상화한 것으로, DOM의 일부분이 아니다.

 

window 객체란?

 

JavaScript에서 window 객체는 브라우저 창을 나타내며, 모든 전역 변수와 메서드를 포함한다. 즉, window 객체는 전역 스코프(Global Scope)를 나타내며, 브라우저의 전역 객체(Global Object)이다.

 

window 객체는 브라우저 창의 속성과 메서드를 제공합니다. 예를 들어, window 객체를 사용하여 현재 창의 너비와 높이, URL, 브라우저 타이틀 등을 가져올 수 있다. 또한, window 객체는 타이머 함수와 이벤트 핸들러 등을 포함하여 다양한 내장 메서드를 제공한다.

 

또한, window 객체는 웹 페이지에서 사용할 수 있는 모든 전역 변수와 함수를 포함한다. 따라서, 전역 변수나 함수를 선언할 때, window 객체를 명시적으로 사용하지 않아도 된다.

 

예를 들어, var a = 10;과 같이 전역 변수를 선언하면, 이 변수는 window 객체의 프로퍼티로 자동으로 등록됩니다. 따라서, window.a와 a는 동일한 변수를 참조한다.

 

 

 

 

이번 과정은 DOM에 집중하자!

document 노드가 최상위 노드가 되고, 밑으로 element 노드가 오며, 이어 text 노드attribute 노드가 오는 계층적인 구조임을 알 수 있다. 이러한 노드 타입에는 총 12개가 있는데 가장 중요한 것은 위에서도 명시가 되어 있듯 총 4가지의 노드가 있다.

 

위 구조는 트리 자료구조로 노드들의 계층 이루어져 있다. 계층 구조로 이루어져 있기 때문에 부모-자식 관계, 형제관계를 표현하는 비선형 자료구조를 나타낸다. 여기서 비선형 자료 구조란 데이터 요소들 간에 계층적 또는 그래프 관계를 가지는 자료구조를 말한다. (트리 자료구조 데이터 간의 관계가 1:1 관계가 아닌 경우에 사용)

 

 

⭐ DOM의 정적 생성
HTML 파일에 적혀 있는 코드를 위에서부터 아래로 읽어내려가며 생성하는 과정

⭐ DOM의 동적 생성
자바스크립트를 이용해 있던 노드에 없는 노드를 만들어 이어 붙이는 것

 

 

document node (문서 노드)

DOM Tree에서 최상위 루트 노드를 나타내며, document 객체를 가리킨다.

 

element node (요소 노드)

모든 HTML 요소 (body, h2, div 등)는 이 요소 노드이다. 속성 노드를 가질 수 있는 유일한 노드로서, 부모-자식 관계를 가지게 되기 때문에 계층적 구조를 이룰 수 있게 된다.

 

attribute node (속성 노드)

모든 HTML 요소의 속성은 이 속성 노드이다. 요소 노드에 대한 정보를 가지고 있다. 그렇기 때문에 부모 노드가 아닌 해당 노드와 연결(바인딩)이 되어 있다.

 

text node (텍스트 노드)

HTML 문서의 모든 텍스트는 이 텍스트 노드라 해도 과언이 아나다. 텍스트 노드는 정보를 표현하며, 가장 마지막에 위치하는 자식 노드이기 때문에 잎사귀를 닮았다 해 리프 노드라고 불리기도 한다.

 

이 4가지 노드들이 존재함으로써 스크립팅 언어가 웹페이지에 접근하고 조작할 수 있게 된다. 특히 데이터 검색하기가 빠른 트리 구조로 이뤄져 있기 때문에 이 접근하고 조작하여 업데이트를 하는 속도는 빠른 편이다.

 

 

시나리오 코드 1
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
    <h2>index9.html 파일</h2>
    <!-- DOM 정적 생성 -->
    <script>

        // div 요소를 생성해 보자. (JS)
        let div = document.createElement("div");
        console.log(div);
        
        document.body.append(div);
        div.textContent = "div 노드를 js를 통해 만들어 보자";
        div.style.backgroundColor = "yellow";

    </script>

</body>
</html>

 

 

 

시나리오 코드 2
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>index10.html</title>
</head>
<body>

    <h2>index10.html 파일</h2>
    <h1 id="title">Hello, World!</h1>
    <button id="changeButton">Change Text</button>

    <script>
        
        // 자바 스크립트를 사용하여 DOM을 조작해 보자.

        // button 요소 id 값인 changeButton 노드에 접근해 보기
        let changeBtn = document.getElementById("changeButton");
        console.log(typeof changeBtn);
        console.log(changeBtn);

        // 함수 표현식 - 함수를 변수 안에 저장하는 법
        let clickEvent = function(){
            let titleElement = document.getElementById("title");
            titleElement.textContent = "안녕 스크립트야아아아 !";
            titleElement.style.color = "blue";
        };

        // 이벤트리스너를 등록해 보자.
        // changeBtn.addEventListener("click",function(){
        //     alert("11111");
        // });

        // changeBtn.addEventListener("click",clickEvent);

        // 직접 이벤트 핸들러 처리를 만들어보자 (JS언어)
        changeBtn.addEventListener("click",function(){
            changeBtn.style.padding = "10px";
            changeBtn.textContent = "바꿔";
        });

    </script>

</body>
</html>

 

 

 

3. DOM에 접근할 수 있는 5가지 방법

메서드 설명

getElementById(id) ID를 기반으로 엘리먼트를 선택합니다.
getElementsByClassName(className) 클래스 이름을 기반으로 모든 엘리먼트를 선택합니다.
getElementsByTagName(tagName) 태그 이름을 기반으로 모든 엘리먼트를 선택합니다.
querySelector(selector) CSS 선택자를 기반으로 첫 번째 엘리먼트를 선택합니다.
querySelectorAll(selector) CSS 선택자를 기반으로 일치하는 모든 엘리먼트를 선택합니다.

 

 

 

시나리오 코드 3
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

    <h2>index11.html 파일</h2>
    <div id="myDiv">아이디로 접근!!!</div>
    <div class="myClass">클래스 11111</div>
    <div class="myClass">클래스 22222</div>

    <p>태그 이름으로 접근1</p>
    <p>태그 이름으로 접근2</p>

    <script>

        // 1. 요소의 id 값으로 접근하기
        let byMyDiv = document.getElementById("myDiv");
        console.log(byMyDiv.textContent);

        // 2. 요소의 class 속성을 사용해서 접근하기
        let byClassNameElements = document.getElementsByClassName("myClass");
        console.log(typeof byClassNameElements);
        byClassNameElements[0].textContent = "동적 렌더링 1";
        byClassNameElements[1].textContent = "동적 렌더링 2";

        // 3. 요소 태그 이름으로 접근해보기
        let byTagName = document.getElementsByTagName("p");
        console.log(byTagName[1].textContent);

        // 4. querySelector 사용해 보기
        // 제공된 CSS 선택자와 일치하는 문서 내의  첫번째 엘리먼트를 반환한다.
        // 만약 일치하는 엘리먼트가 없다면 null 값을 반환한다.
        let byQuerySelector = document.querySelector(".myClass");
        console.log("-------------");
        console.log(byQuerySelector);

        // 5. querySelectorAll 사용해보기
        // CSS 선택자와 일치하는 모든 엘리먼트를 NodeList로 반환한다.
        let byQuerySelectorAll = document.querySelectorAll(".myClass");
        console.log("==============");
        console.log(typeof byQuerySelectorAll);
        console.log(byQuerySelectorAll);
        byQuerySelectorAll[1].textContent = "안녕 QuerySelectorAll";
        byQuerySelectorAll[1].style.color = "red";

    </script>

</body>
</html>

 

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
    <h2>index12.html 파일</h2>
    <div class="flex--container">
        <img id="toggleImage" src="/img/img1.png" alt="">
        <button onclick="toggleImage()">이미지 토글</button>
        <button onclick="toggleImage2()">이미지 토글</button>
    
    </div>
    <script>

        let isImage1 = true;
        function toggleImage(){
            const imgElement = document.querySelector("toggleImage");
            if(isImage1){
                imgElement.src = "/img/img2.png";
            } else{
                imgElement.src = "/img/img1.png";
            }
            isImage1 = !isImage1;
        }

        function toggleImage2(){
            let imgNode = document.getElementById("toggleImage");

            if(imgNode.src.includes("img1.png")){
                imgNode.src = "img/img2.png";
            } else {
                imgNode.src = "img/img1.png";
            }
        }

    </script>
</body>
</html>

 

 

 

요약

DOM은 JavaScript 언어를 사용해서 문서에 접근하여 읽고 조작할 수 있도록 API를 제공하는 문서 객체 모델이다.

728x90