목차
브라우저에 띄울 웹 페이지가 단순히 정보 전달만을 목적으로 하는 정적인 웹이라면 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가지 노드들이 존재함으로써 스크립팅 언어가 웹페이지에 접근하고 조작할 수 있게 된다. 특히 데이터 검색하기가 빠른 트리 구조로 이뤄져 있기 때문에 이 접근하고 조작하여 업데이트를 하는 속도는 빠른 편이다.
2. JS로 DOM 조작해보기
시나리오 코드 1 - DOM 조작해보기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.ddiivv {
color: blue;
}
</style>
</head>
<body>
<h2>index9.html 파일 입니다.</h2>
<!-- DOM 정적 생성 -->
<script>
// div 요소를 생성해보자. (JS)
let div = document.createElement("div");
console.log(div);
document.body.append(div);
div.style.backgroundColor = "yellow";
div.className = "ddiivv";
div.textContent = "div 노드를 js를 통해 만들어 보자";
</script>
</body>
</html>
미리 css를 작성해두고 상황에 따라 div를 추가해서 class를 부여하면 준비된 스타일을 적용시킬 수 있다.
시나리오 코드 2
<!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>index10.html 파일 입니다.</h2>
<h1 id="title">Hello, World!</h1>
<button id="changeButton" onclick="">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", clickEvent);
let flag = true;
changeBtn.addEventListener("click", function() {
// 직접 이벤트 핸들러 처리 만들기(js)
if (document.getElementById("changeButton").textContent == "Change Text") {
document.getElementById("changeButton").textContent = "Changed Text"
flag = false;
} else {
document.getElementById("changeButton").textContent = "Change Text"
flag = true;
}
});
</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>
<body>
<h2>index11.html 파일입니다.</h2>
<div id="myDiv">아이디로 접근</div>
<div class="myClass">정적 렌더링 1</div>
<div class="myClass">정적 렌더링 2</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 = "blue"
</script>
</body>
</html>
4. 연습문제
![]() |
![]() |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.flex--container {
display: flex;
}
</style>
</head>
<body>
<h2>index12.html 파일입니다.</h2>
<div class="flex--container">
<img src="images/images1.png" alt="">
<button onclick="toggleImage2()">이미지토글</button>
</div>
<script>
let flag = true;
function toggleImage() {
if (flag) {
document.querySelector("img").src = "images/images2.png";
} else {
document.querySelector("img").src = "images/images1.png";
}
flag = !flag;
}
function toggleImage2() {
let imageNode = document.querySelector("img");
if(imageNode.src.includes("images1.png")) {
alert("sdfs");
ImageNode.src = "images/images2.png";
} else {
ImageNode.src = "images/images1.png";
}
}
</script>
</body>
</html>
요약
DOM은 JavaScript 언어를 사용해서 문서에 접근하여 읽고 조작할 수 있도록 API를 제공하는 문서 객체 모델이다.
'JS > JavaScript 핵심' 카테고리의 다른 글
JS - 점검 6(웹 페이지 렌더링 과정) (2) | 2024.07.23 |
---|---|
JS - 점검 5(Browser Object Model) (0) | 2024.07.23 |
JS - 점검 2(객체와배열) (0) | 2024.07.19 |
JS - 점검 1(데이터 타입 및 연산) (0) | 2024.07.18 |
JS - 사전 기반 지식 (0) | 2024.07.18 |