DOM(Document Object Model)

2022. 11. 29. 13:15·Development/WEB
반응형

DOM은 웹 문서 제어를 위한 프로그래밍 인터페이스다.
웹 상의 문서 내용과 문서의 구조를 구성하는 항목들(div, span, input 등)은 모두 object들이다. DOM은 이를 메모리에 계층으로 표현하며(그림 1) 이들을 제어(생성, 변형, 삭제 등)할 수 있도록 돕는 프로그래밍 인터페이스다. 이를 위해 API가 제공되며, 이들 API들은 브라우저에 이미 저장된 기능들이다. 따라서 DOM을 이용하면 웹 문서의 구조나 스타일, 내용을 바꿀 수 있다. 
DOM 자체는 프로그래밍 언어가 아니기 때문에 DOM을 이용하기 위해서는 주로 javascript와 같은 스크립트 언어를 이용한다.

그림 1. 브라우저는 HTML 문서를 읽을 때, 마치 나무와 같이 각 태그 요소들을 재조립하여 DOM 트리를 구성한다. 따라서 웹 페이지는 가장 상위의 <html> 태그부터 시작하여 계층 관계를 이룬다.

DOM API에는 기본적으로 다음의 것들이 있다.

  • querySelector
  • querySelectorAll
  • addEventListener
  • classList.add
  • classList.contains
  • classList.remove
  • textContent
  • getElementById
  • createElement
  • appendChild

querySelector

가장 먼저 찾은 HTML 요소 하나만 반환한다.

querySelectorAll

찾아낸 모든 HTML 요소를 반환한다. -> 유사 배열이 된다.

 

이들 querySelector와 querySelectorAll은 깊이 우선 탐색(DFS)을 이용하여 특정 요소를 찾아낸다. querySelector의 경우 요소를 찾아내면 곧바로 종료되고, querySelectorAll의 경우 모든 노드를 방문할 것이다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css/main.css" />
    <script defer src="./js/main.js"></script>
</head>
<body>
    <div class="div">div element 1</div>
    <div class="div">div element 2</div>
    <div class="div">div element 3</div>
    <div class="div">div element 4</div>
    <div class="div">div element 5</div>
</body>
</html>
const divElem = document.querySelector('.div');
console.log('querySelector result: ', divElem);

const divElems = document.querySelectorAll('.div');
console.log('querySelectorAll result: ', divElems);

result of querySelector, querySelectorAll

addEventListener

addEventListener는 querySelector나 querySelectorAll 등으로 찾은 요소에 대하여 특정 이벤트가 발생하는지 감시하고, 해당 이벤트가 발생하면 익명 함수(핸들러)를 실행시킨다.

const divElem = document.querySelector('.div');
// console.log('querySelector result: ', divElem);

const divElems = document.querySelectorAll('.div');
// console.log('querySelectorAll result: ', divElems);

divElem.addEventListener('click', function() {
    console.log('divElem addEventListener Executed.');
});

divElems.addEventListener('click', function() {
    console.log('divElems addEventListener Executed.');
});

result of addEventListener after querySelector

위 결과는 querySelector로 찾은 요소에 대한 addEventListener의 결과로서, 이벤트는 click이고 핸들러로 실행하는 함수는 console 출력이다. 

querySelectorAll도 적용했기 때문에 클릭했을 시에 두 개의 결과가 떠야 한다. 그러나 querySelectorAll로 찾은 요소에 대해서는 위와 같이 코드를 작성할 경우 클릭해도 핸들러가 작동하지 않는데, 그 이유는 querySelectorAll는 일련의 여러 요소들을 유사 배열로 반환하기 때문이다. 따라서 forEach를 이용하여 각 요소에 하나하나 접근해야 한다.

const divElem = document.querySelector('.div');
// console.log('querySelector result: ', divElem);

const divElems = document.querySelectorAll('.div');
// console.log('querySelectorAll result: ', divElems);

divElem.addEventListener('click', function() {
    console.log('divElem addEventListener Executed.');
});

divElems.forEach(function(item, index) {
    item.addEventListener('click', function() {
        console.log(`divElems- item: ${item}, index: ${index}`);
    })
});

result of addEventListener after querySelector & querySelectorAll

div element 1을 클릭할 경우 querySelector에 대한 addEventListener가 실행된 결과와 querySelectorAll에 대한 addEventListener가 실행된 결과가 모두 보여지게 된다.

 

textContent

textContent는 특정 요소가 가지고 있는 텍스트를 반환할 수 있고, 값을 넣을 수도 있게 한다.

const divElem = document.querySelector('.div');
// console.log('querySelector result: ', divElem);

const divElems = document.querySelectorAll('.div');
// console.log('querySelectorAll result: ', divElems);

divElem.addEventListener('click', function() {
    console.log('divElem addEventListener Executed.');
});

divElems.forEach(function(item, index) {
    item.addEventListener('click', function() {
        console.log(`divElems- textContent: ${item.textContent}`);
        console.log(`divElems:`, item);
    })
});

result of textContent

const divElem = document.querySelector('.div');
// console.log('querySelector result: ', divElem);

const divElems = document.querySelectorAll('.div');
// console.log('querySelectorAll result: ', divElems);

divElem.addEventListener('click', function() {
    console.log('divElem addEventListener Executed.');
});

divElems.forEach(function(item, index) {
    item.addEventListener('click', function() {
        console.log(`divElems- textContent: ${item.textContent}`);
        console.log(`divElems:`, item);
        item.textContent = `textContent ${index}`;
        console.log(`divElems- textContent: ${item.textContent}`);
        console.log(`divElems:`, item);
    })
});

result of textContent

textContent를 이용하면 특정 요소가 가진 텍스트를 반환받을 수도 있고, 초기화 할 수도 있다. 위 예시는 div element 1, 2까지를 클릭한 결과로서 텍스트 자체가 변경된 것을 확인할 수 있다.

 

classList

classList를 이용하면 특정 요소에 class를 추가, 삭제, 확인이 가능하다.

classList.add

classList.add는 class를 추가한다. 

const divElem = document.querySelector('.div');
// console.log('querySelector result: ', divElem);

const divElems = document.querySelectorAll('.div');
// console.log('querySelectorAll result: ', divElems);

divElem.addEventListener('click', function() {
    console.log('divElem addEventListener Executed.');
});

divElems.forEach(function(item, index) {
    item.addEventListener('click', function() {
        item.classList.add(`${index}`)
        console.log(`divElems- textContent: ${item.textContent}, index: ${index}`);
        console.log('divElems: ', item);
    })
});

result of classList.add

classList.contains

특정 클래스 요소가 있는지 검사한다.

const divElem = document.querySelector('.div');
// console.log('querySelector result: ', divElem);

const divElems = document.querySelectorAll('.div');
// console.log('querySelectorAll result: ', divElems);

divElem.addEventListener('click', function() {
    console.log('divElem addEventListener Executed.');
});

divElems.forEach(function(item, index) {
    item.addEventListener('click', function() {
        item.classList.add(`${index}`)
        console.log(`divElems- textContent: ${item.textContent}`);
        console.log(`divElem:`, item);
        console.log('classList.contains:', item.classList.contains(`${index}`));
    })
});

result of classList.contains

classList.remove

classList.remove는 특정 요소가 가진 특정 클래스를 지운다.

const divElem = document.querySelector('.div');
// console.log('querySelector result: ', divElem);

const divElems = document.querySelectorAll('.div');
// console.log('querySelectorAll result: ', divElems);

divElem.addEventListener('click', function() {
    console.log('divElem addEventListener Executed.');
});

divElems.forEach(function(item, index) {
    item.classList.add(`${index}`);
    console.log('divElems:', item);
});

divElems.forEach(function(item, index) {
    item.addEventListener('click', function() {
        item.classList.remove(`${index}`);
        console.log('divElems: ', item);
    });
});

result of classList.remove

getElementById

getElementById는 id 속성과 일치하는 HTML element를 찾아낸다. id는 element별로 유일하기 때문에 특정 element를 빠르게 지정할 수 있다.

createElement

createElement는 지정한 HTML element를 만들어 반환한다.

appendChild

DOM은 HTML element들을 노드로 하는 일종의 트리다. appendChild는 createElement로 만든 노드(element)를 자식 노드로 하여 특정 노드(parent)에 붙인다. 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css/main.css" />
    <script defer src="./js/main.js"></script>
</head>
<body>
    <div id="div"></div>
</body>
</html>
const divElem = document.getElementById('div');
const elem = document.createElement('h1');
elem.textContent = 'RaphDohk';
divElem.appendChild(elem);

result of getElementById, createElement, appendChild

지금까지 살펴본 것과 같이 DOM을 직접 제어할 수 있지만, 페이지 리로딩 시간이 늘어날 수 있다. 그래서 가상 DOM 개념이 등장했고, 이 가상 DOM을 이용하여 리랜더링 시간을 줄이는 React가 등장했다. 

가상 DOM은 일종의 복사본인데, 기존의 요소와 비교하여 변경된 요소들을 파악하여 이를 리랜더링하기 때문에 빠르다고 볼 수 있다.


- https://ko.wikipedia.org/wiki/%EB%AC%B8%EC%84%9C_%EA%B0%9D%EC%B2%B4_%EB%AA%A8%EB%8D%B8
- https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction

 

문서 객체 모델 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 문서 객체 모델(영어: Document Object Model 도큐먼트 오브젝트 모델[*], DOM)은 XML, HTML 문서의 각 항목을 계층으로 표현하여 생성, 변형, 삭제할 수 있도록 돕는 인터

ko.wikipedia.org

 

Introduction to the DOM - Web APIs | MDN

The Document Object Model (DOM) is the data representation of the objects that comprise the structure and content of a document on the web. This guide will introduce the DOM, look at how the DOM represents an HTML document in memory and how to use APIs to

developer.mozilla.org

 

- https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById

 

Document.getElementById() - Web APIs | MDN

The Document method getElementById() returns an Element object representing the element whose id property matches the specified string. Since element IDs are required to be unique if specified, they're a useful way to get access to a specific element quick

developer.mozilla.org

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

 

Document.createElement() - Web API | MDN

HTML 문서에서, Document.createElement() 메서드는 지정한 tagName의 HTML 요소를 만들어 반환합니다. tagName을 인식할 수 없으면 HTMLUnknownElement (en-US)를 대신 반환합니다.

developer.mozilla.org

- https://developer.mozilla.org/ko/docs/Web/API/Node/appendChild

 

Node.appendChild() - Web API | MDN

Node.appendChild() 메소드는 한 노드를 특정 부모 노드의 자식 노드 리스트 중 마지막 자식으로 붙입니다. 만약 주어진 노드가 이미 문서에 존재하는 노드를 참조하고 있다면 appendChild() 메소드는 노

developer.mozilla.org

 

반응형
저작자표시 비영리 변경금지 (새창열림)

'Development > WEB' 카테고리의 다른 글

이미지 렌더링 & Raster와 Vector  (0) 2022.12.01
서버, 클라이언트, 프로토콜, 통신, 웹 표준  (0) 2022.11.30
[FastCampus] '프로그래밍 첫걸음 시작하기' 강의 노트  (0) 2019.08.29
'Development/WEB' 카테고리의 다른 글
  • 이미지 렌더링 & Raster와 Vector
  • 서버, 클라이언트, 프로토콜, 통신, 웹 표준
  • [FastCampus] '프로그래밍 첫걸음 시작하기' 강의 노트
doh.k
doh.k
  • doh.k
    DOHk's DevLog
    doh.k
  • 전체
    오늘
    어제
    • 분류 전체보기
      • DailyLog
      • TIL
      • Project
        • Development
        • Artificial Intelligence
      • Development
        • Database
        • WEB
        • CSE
        • javascript
        • Algorithms
        • Linux
        • Network
        • Python
        • 라즈베리파이
        • Apple
      • Research
        • 논문
        • 금융,블록체인
        • Time-Series
        • 수학
        • 미적분학
        • 화학
      • Artificial Intelligence
        • Machine Learning
        • Deep Learning
        • TensorFlow
        • ReinforcementLearning
      • 기타
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    경사하강법
    데이터
    딥러닝
    ssh
    데이터베이스
    JavaScript
    맥북
    라즈베리파이
    파이썬
    아이패드
    Algorithms
    gradient descent
    블록체인
    자료구조
    gradient
    머신러닝
    리눅스
    기계학습
    Linux
    Spring
    자바스크립트
    가상화폐
    Python
    Network
    Machine Learning
    Mac
    스프링
    알고리즘
    네트워크
    pycharm
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
doh.k
DOM(Document Object Model)
상단으로

티스토리툴바