DOM (Document Object Model)
- HTML 문서를 Javascript로 조작하기 위한 모델
- HTML, XML 문서의 프로그래밍 인터페이스이며, 문서의 구조를 계층적인 노드로 나타냄
- W3C(World Wide Web Consortium) 표준
DOM의 구성 요소
- 문서 노드 (Document) : 최상위 노드로 HTML 문서 전체를 대표
- 요소 노드 (Element) : HTML 태그를 나타냄
- 속성 노드 (Attribute) : 요소의 속성을 나타냄
- 텍스트 노드 (Text) : 요소 안의 텍스트를 나타냄
- 주석 노드 (Comment) : HTML 주석을 나타냄
DOM의 특징
- 트리 구조
- 부모-자식 관계로 구성된 계층적 구조이며, 이를 DOM 트리라고 함
- 부모, 자식, 형제 노드 간의 관계를 통해 문서를 탐색하거나 조작 가능
- 라이브 (Live)
- DOM 객체는 라이브 객체로 변경이 발생하면 즉시 웹 페이지에 반영
- 조작 가능
- 자바스크립트를 사용하여 DOM 요소를 선택, 수정, 추가 또는 제거 가능
DOM 요소 선택
- document.getElementById(id) : 주어진 ID를 가진 요소를 반환
- 단, <p> 태그 위에 <script>를 작성하게 되면 DOM 렌더링 시점 문제 때문에 console에는 null이 찍히게 됨
- 웹 페이지는 HTML, CSS, JavaScript 파일을 순차적으로 처리하고 렌더링하는데, 스크립트가 DOM 요소에 접근하려면 해당 요소들이 이미 로드되어 있어야 하기 때문
순서를 </body> 이전에 작성하거나 DOMContentLoaded 이벤트 사용
<body>
<script>
let pTag = document.getElementById("testId");
console.log(pTag);
</script>
<p id="testId">p 태그</p>
</body>
</body> 태그 바로 위에 <script> 작성
<body>
<p id="testId">p 태그</p>
<script>
let pTag = document.getElementById("testId");
console.log(pTag);
</script>
</body>
- document.getElementsByTagName(name) : 주어진 태그 이름을 가진 요소들의 목록을 반환
- document.getElementsByClassName(name) : 주어진 클래스 이름을 가진 요소들의 목록을 반환
- document.querySelector(selector) : 주어진 CSS 선택자와 일치하는 첫 번째 요소를 반환
- document.querySelectorAll(selector) : 주어진 CSS 선택자와 일치하는 모든 요소의 목록을 반환
DOM 조작
- 웹 페이지의 요소를 동적으로 변경하거나 조작하는 방법
- 이를 통해 HTML 구조와 콘텐츠를 실시간으로 업데이트 가능
텍스트 변경
- textContent 또는 innerText를 사용하여 요소의 텍스트 내용을 변경 가능
<body>
<p id="textElement">Hello, world!</p>
<button onclick="changeText()">Change Text</button>
<script>
function changeText() {
// 텍스트 변경
document.getElementById("textElement").textContent = "Hello, DOM!";
document.getElementById("textElement").style.color = "red";
}
</script>
</body>
속성 변경
- setAttribute() 메서드를 사용하여 HTML 요소의 속성을 변경 또는 특정 속성에 대해 직접 접근하여 값을 변경 가능
setAttribute('속성', '값')
<body>
<img id="myImage" src="image1.jpg" alt="Old Image">
<button onclick="changeAttribute()">Change Image</button>
<script>
function changeAttribute() {
// 속성 변경 (src, alt)
document.getElementById("myImage").setAttribute("src", "image2.jpg");
document.getElementById("myImage").setAttribute("alt", "New Image");
}
</script>
</body>
클래스 추가/삭제
- classList는 DOM 요소의 클래스를 조작하는데 사용되는 속성
- add(), remove(), toggle() 등의 메서드를 사용하여 클래스를 추가하거나 삭제 가능
- toggle() : 클래스가 존재하면 삭제하고, 존재하지 않으면 추가
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Class Manipulation Example</title>
<style>
.highlight {
color: red;
font-weight: bold;
}
</style>
</head>
<body>
<p id="myParagraph">This is a paragraph.</p>
<button onclick="toggleClass()">Toggle Highlight</button>
<script>
function toggleClass() {
// 'highlight' 클래스를 추가하거나 제거
document.getElementById("myParagraph").classList.toggle("highlight");
}
</script>
</body>
</html>
요소 생성
- createElement()를 사용하여 새로운 HTML 요소를 동적으로 생성 가능
<body>
<div id="container"></div>
<button onclick="createElementFunction()">Create Paragraph</button>
<script>
function createElementFunction() {
// 새 <p> 요소 생성
let newParagraph = document.createElement("p");
newParagraph.textContent = "This is a new paragraph.";
// 새로운 요소를 <div id="container"> 안에 추가
document.getElementById("container").appendChild(newParagraph);
}
</script>
</body>
- 예제 설명
- createElement("elementName")로 새로운 요소를 생성하고, textContent로 텍스트를 설정합니다.
- appendChild()를 사용하여 생성된 요소를 특정 부모 요소에 추가
- 버튼 클릭 시 새로운 <p> 요소가 생성되어 id가 container인 요소에 추가
요소 삽입
- appendChild(), insertBefore() 등을 사용하여 새로 생성한 요소를 다른 요소에 삽입
<body>
<div id="container">
<p>First Paragraph</p>
</div>
<button onclick="insertElement()">Insert Paragraph Before</button>
<script>
function insertElement() {
// 새 <p> 요소 생성
let newParagraph = document.createElement("p");
newParagraph.textContent = "This paragraph is inserted before the first one.";
// 새 요소를 첫 번째 <p> 요소 앞에 삽입
let container = document.getElementById("container");
container.insertBefore(newParagraph, container.firstChild);
}
</script>
</body>
- 예제 설명
- insertBefore(newNode, referenceNode)는 newNode를 referenceNode 앞에 삽입
- 버튼을 클릭하면 새 <p> 요소가 첫 번째 <p> 요소 앞에 삽입
요소 삭제
- removeChild()를 사용하여 부모 요소에서 자식 요소를 삭제 가능
<body>
<div id="container">
<p id="paragraph">This paragraph will be removed.</p>
</div>
<button onclick="removeElement()">Remove Paragraph</button>
<script>
function removeElement() {
// <p> 요소 삭제
let paragraph = document.getElementById("paragraph");
paragraph.parentNode.removeChild(paragraph);
}
</script>
</body>
이벤트 처리
- 사용자가 웹 페이지와 상호작용하는 방식을 정의하는 중요한 개념
이벤트 리스너 등록 (addEventListener)
- HTML 요소에 이벤트를 연결하는 가장 일반적인 방법
- 이벤트가 발생하면, 지정된 함수(이벤트 핸들러)가 호출
<body>
<button id="myButton">Click Me</button>
<script>
// 버튼 요소 선택
const button = document.getElementById("myButton");
// 이벤트 리스너 등록
button.addEventListener("click", () => {
alert("Button clicked!");
});
</script>
</body>
이벤트 객체 (event)
- 이벤트가 발생하면 브라우저는 이벤트와 관련된 정보가 담긴 event 객체를 핸들러 함수에 전달
- 이 객체를 사용하여 이벤트의 세부 정보를 확인하거나 제어 가능
<body>
<button id="myButton">Click Me</button>
<script>
const button = document.getElementById("myButton");
button.addEventListener("click", (event) => {
console.log("Event Type:", event.type); // 클릭 이벤트 타입
console.log("Target Element:", event.target); // 이벤트 발생한 요소
console.log(event)
});
</script>
</body>
이벤트 버블링과 캡처링
- 이벤트는 DOM 트리 구조를 따라 위로 전파(버블링)되거나 아래로 전파(캡처링)
- 이벤트 버블링
- 이벤트가 가장 안쪽 요소에서 발생한 후, DOM 트리를 따라 상위 요소로 전파
- 기본 동작 방식은 버블링
- 이벤트 캡처링
- 이벤트가 최상위 요소에서 시작하여, DOM 트리를 따라 안쪽 요소로 전파
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Event Bubbling & Capturing</title>
<style>
div {
padding: 20px;
margin: 10px;
border: 1px solid black;
}
</style>
</head>
<body>
<div id="outerDiv">
Outer Div
<div id="innerDiv">
Inner Div
</div>
</div>
<script>
const outerDiv = document.getElementById("outerDiv");
const innerDiv = document.getElementById("innerDiv");
// 버블링 방식 (기본)
outerDiv.addEventListener("click", () => {
alert("Outer Div clicked (Bubbling)");
});
innerDiv.addEventListener("click", () => {
alert("Inner Div clicked (Bubbling)");
});
// 캡처링 방식
outerDiv.addEventListener(
"click",
() => {
alert("Outer Div clicked (Capturing)");
},
true // 캡처링 모드 활성화
);
</script>
</body>
</html>
- 기본 동작 : 버블링
- Inner Div를 클릭하면 Inner Div 핸들러가 먼저 실행되고, 이후 Outer Div 핸들러가 실행
- 캡처링 활성화
- true로 설정된 핸들러는 캡처링 단계에서 실행
- 클릭 시 Outer Div 캡처링 핸들러가 가장 먼저 실행
- Inner Div 클릭 : Outer Div(Capturing) - Inner Div (Bubbling) - Outer Div (Bubbling)
- Outer Div 클릭 : Outer Div(Capturing) - Outer Div(Bubbling
이벤트 전파 중지
- 이벤트가 상위 요소로 전파되는 것을 막고 싶을 때 event.stopPropagation()을 사용
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Stop Propagation</title>
<style>
div {
padding: 20px;
margin: 10px;
border: 1px solid black;
}
</style>
</head>
<body>
<div id="outerDiv">
Outer Div
<div id="innerDiv">
Inner Div
</div>
</div>
<script>
const outerDiv = document.getElementById("outerDiv");
const innerDiv = document.getElementById("innerDiv");
outerDiv.addEventListener("click", () => {
alert("Outer Div clicked");
});
innerDiv.addEventListener("click", (event) => {
alert("Inner Div clicked");
event.stopPropagation(); // 이벤트 전파 중지
});
</script>
</body>
</html>
- Inner Div clicked 실행 후 종료(Outer Div clicked 실행 X)
'Language > Javascript' 카테고리의 다른 글
[개념] ES6이란? (1) | 2024.12.24 |
---|---|
[Javascript] DOM 렌더링 시점 (1) | 2024.12.09 |
[Javascript] 비동기 프로그래밍 [Callback, Promise, async/await] (0) | 2024.12.09 |
[Javascript] Javascript 동작 원리 [동기, 비동기] (0) | 2024.12.06 |
[Javascript] 객체(Object)와 배열(Array) (0) | 2024.12.05 |