웹개발을 본격적으로 학습하다가 막히는 부분이 몇개 있는데 그 중에 하나가 DOM 입니다. DOM은 Document Object Model - 문서 객체 모델의 약자로 쉽게 말하면 웹브라우저에서 HTML의 요소들을 클라이언트에서 이  DOM을 사용해 동적으로 조작하는 것 입니다. (DOM은 돔이라 부른다)

 

왜 이걸 사용하느냐? 웹의 초기로 거슬러 올라가 보면 이해가 쉽습니다. 인터넷 초기에 웹브라우저는 서버에 저장된 정적인 페이지, 혹은 서버에서 DB를 처리하여 동적으로 만든 웹페이지를 주로 전송받아서 표시하는 역할을 했습니다. 그 방법으로도 웹이 돌아가지만 그러면 클라이언트(PC나 스마트폰)는 놀고 있는 것이나 마찬가지 입니다. 페이지 하나를 바꾸려면 전체 페이지를 다시 로드해야 하고 서버의 응답시간은 늘어갑니다.

 

그래서 클라이언트의 자원(CPU, 메모리)을 사용하도록 하자는 취지에서 스크립트 언어를 만들었는데 그것이 LiveScript 입니다. 이름에서 취지가 나타나 있지요. Live 생동감 있는 Script 스크립트를 지향한다는 것입니다. 자바 스크립트로 바꾼 것은 당시 자바가 돌풍을 일으키고 있어서 비슷하게 바꾼 것이지 실제로 두언어는 아무 상관이 없습니다. 일부 문법이 비슷하다고 하는데 그건 너무 퉁친 것이고 실행 환경이나 내부의 로직이 전혀 다른 언어입니다.

 

 

클라이언트에서 스크립트를 사용하는 것은 서버의 역할이 줄이는 것이 아니고 클라이언트가 더 여러가지를 하기 때문에 서버는 더 중요한 작업에 집중하여 더 좋은 웹을 만들 수 있습니다. 그것이 자바스크립트인데 그래서 HTML을 어떻게 하겠다는 건데? - 라는 질문에는 DOM 객체를 사용해서 조작합니다 - 라고 대답할 수 있습니다.

 

DOM을 사용하는 것과 아닌 것의 차이점은 뭐야? 라고 질문하면 예를 들어서 NODE.JS는 DOM이 없습니다. 왜냐하면 NODE.JS는 서버에서 독립적으로(Stand Alone) 작동하는 시스템이기 때문입니다. NODE.JS에서 HTML 파일을 생성해 줄 수 있어도 DOM은 없습니다. DOM은 웹브라우저에서 사용하기 때문에 브라우저에서 자바스크립트로 HTML을 조작할 때 필요합니다.

 

예제를 보는 것이 이해가 빠를 겁니다.

 

아래의 HTML 파일에서 body 요소를 DOM으로 조작해보겠습니다.

 

<!DOCTYPE html>
<html lang="ko">
<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">

    <link rel="stylesheet" href="./style.css">
    <script src="./app.js" defer></script>
    
    <title>Document</title>
</head>
<body>
    
</body>
</html>

 

자바 스크립트에서 body 요소에 해당하는 DOM 객체에 액세스합니다. 그리고 거기다가 텍스트를 채워넣습니다. Hello, World! 가 출력됩니다. append 는 계속해서 추가할 때 사용하는 메소드입니다.

 

const body = document.body;

body.append("Hello, ");
body.append("World!");

 

append나 appendChild 메소드로 요소를 추가할 수 있는데 이렇게 하다보면 자바스크립트만으로도 HTML 문서를 만들 수 있습니다. createElement로 원하는 요소를 만들어서 사용할 수 있습니다. html의 모든 태그가 가능합니다.

 

appendChild로 노드의 자식에게 붙이는 방식입니다. 이렇게 하면 <body><div>안녕하세여?</div></body> 처럼 나옵니다. createElement로 태그 요소를 만든 후에 이를 상위(부모) 요소에 갖다 붙입니다. 

 

const body = document.body;

let container = document.createElement('div');

container.innerText = "안녕하세여?";

// body.append(container);
body.appendChild(container);

 

아, html 태그를 요소라고 하며 이것을 요소 노드라고 하는데 모든 노드가 요소는 아닙니다. 요소(element)는  자식을 가질 수 있지만 텍스트 노드(Text Node)같이 자식이 없는 노드도 있습니다. 이런 이야기는 들어도 복잡하니까 그 전에 실습을 더 해보겠습니다.

 

이번엔 h1을 만들어서 body 에 붙여봅니다. 속성도 지정해봅니다. html 문법에 입히는 거니까 html을 알고 있다면 더 수월합니다. (순서가 html -> css -> javascript로 배워야함)

const dc = document;
const body = dc.body;

const title = dc.createElement('h1');
title.textContent = '타이틀';
title.setAttribute('title', '블로그-타이틀');

body.append(title);

 

아래의 코드는 div 컨테이너 안에 h1을 넣는 코드입니다. 포함관계를 잘 생각해서 넣습니다.

const dc = document;
const body = dc.body;
const container = dc.createElement("div");
container.innerText = "메인 컨테이너";
container.classList.add("container");

const title = dc.createElement('h1');
title.classList.add('title');
title.innerText = "타이틀";

body.append(container);
container.append(title);

DOM 조작

 

innerText 와 textContent, innerHTML

DOM의 요소를 사용해서 그 안의 텍스트를 바꿀 때는 innerText나 textContent를 사용합니다. 둘다 텍스트인데 textContent의 경우 console.log에서 보여질 때는 display 설정에 상관없이 풀로다가 출력합니다. 

 

innerHTML은 태그를 넣을 수가 있는데  보안문제가 있어서 브라우저에서는 거의 쓰이지 않습니다.

 

요소 가져오기 (querySelector)

다음의 HTML에서 ul 요소를 가져와서 아래로 li를 채우려고 합니다.

<body>
    <div class="container">
        <h1 class="heading">DOM 예제</h1>

        <ul class="myList">
            <li>첫번째 항목</li>
        </ul>
    </div>    
</body>

 

querySelector를 사용하고 for문을 돌려봅니다. class는 .이고 id는 #을 이름앞에 붙입니다.

const dc = document;
const myList = dc.querySelector('.myList');


for (let i=1; i<=3; i++) {
    let item = dc.createElement('li');
    item.innerText = i + " 번째 항목";
    myList.append(item);
}

 

다음과 같이 출력합니다. 이제 뭔가 동적인 느낌이 나기 시작합니다.

 

 

요소삭제하기 remove

위의 코드에서 ul의 자식 노드는 한개가 아닙니다. 인덱싱을 정확하게 알아두고  remove 메소드로 제거합니다. 

 

myList.childNodes[5].remove();

 

노드 리스트를 콘솔에 출력해 보면 의외로 다른 부분이 있으니 잘 확인합니다. 삭제하는 방법이 하나가 아니라 여러 메소드가 있으니까 상황에 적당한 방법을 선택합니다.

 

 

CSS style 속성

DOM으로 CSS style도 바꿀 수 있습니다. 한가지 주의사항은 CSS에서 background-color 처럼 표기된 것은 js에서 backgroundColor 처럼 - 가 없어지고 뒤에 단어의 첫글자가 대문자로 바뀝니다.

 

const body = document.body;
body.style.backgroundColor = "green";
body.style.color = "white"

 

 

DOM 스타일 예제

공유하기

facebook twitter kakaoTalk kakaostory naver band