본문 바로가기
WEB/JS

[JS] 문서 객체 모델

by snow_white 2022. 2. 11.

문서 객체 모델의 정의

Document Object Model을 줄여 DOM으로 표기하는 문서 객체 모델은

웹 문서의 모든 요소를 자바스크립트를 이용하여 조작할 수 있도록 객체를 사용해 문서를 해석하는 방법이다.

 

  • 문서 객체

HTML 태그를 자바스크립트에서 사용할 수 있는 객체

 

  • 노드

요소 노드와 텍스트 노드로 구분

텍스트 노드를 갖지 않는 태그 : <br> <hr> <img>

 

  • 정적 생성

웹 페이지를 처음 실행할 때 HTML 태그로 적힌 문서 객체를 생성하는 것

 

  • 동적 생성

웹 페이지 실행 중에 자바스크립트를 사용해서 문서 객체를 생성하는 것

 

  • 웹페이지 실행 순서

 

아래는 오류 코드임

<head>
    <script>
        // h1 태그의 배경 색상을 변경합니다.
        document.querySelector('h1').style.backgroundColor = 'red';

        // h2 태그의 글자 색상을 변경합니다.
        document.querySelector('h2').style.color = 'red';
    </script>
</head>
<body>
    <h1>Process - 1</h1>
    <h2>Process - 2</h2>
</body>

웹 브라우저가 위쪽에서 아래쪽으로 코드를 실행하기 때문에 script 태그에서 h1h2를 찾을 수 없다따라서

 

script 태그를 body 내부로 옮겨 위치 시킨다.

이벤트를 활용한다.

<script>
        window.onload = function () {
            // h1 태그의 배경 색상을 변경합니다.
            document.querySelector('h1').style.backgroundColor = 'red';

            // h2 태그의 글자 색상을 변경합니다.
            document.querySelector('h2').style.color = 'red';
        };
</script>

 

  • <script> 태그의 위치

가장 위의 head 태그에 넣으면 위쪽부터 차근차근 script 태그를 읽기 때문에 body 안에 있는 구조물들이 화면이 보이지 않고, 빈 화면 상태로 대기해야 함

 

반면 body 태그의 맨 아래쪽에 넣는다면 script 태그 실행 전에 화면이 먼저 구성되어 화면이 모두 떴는데도 로딩 중메시지가 나타남

 

=> 현재는 AMD 기술을 사용해 head 태그 내부에 script 태그를 입력해도 웹 페이지가 빠르게 표시할 수 있다!

 

  • 문서 객체 선택
<script>
        // 이벤트를 연결합니다.
        window.onload = function () {
            // 문서 객체를 선택합니다.
            var header = document.getElementById('header');
            // 문서 객체를 조작합니다.
            header.style.color = 'orange';
            header.style.background = 'red';
            header.innerHTML = 'From JavaScript';
        };
</script>
구분 메서드 설명
1개 선택 document_getElementById(아이디) 아이디로 1개 선택
document_querySelector(선택자) 선택자로 1개 선택 (#id, .class, 태그 이름 사용)
여러 개 선택

document_getElementsByName(이름) name 속성으로 여러 개 선택
document_getElemetsByClassName(클래스) class 속성으로 여러 개 선택
document_querySelectorAll(선택자) 선택자로 여러 개 선택
document_getElementsByTagNamel(태그이름) 태그 이름으로 여러 개 선택

문서 객체를 여러 개 선택하는 메서드를 사용하면 문서 객체가 배열 형태로 반환된다.

 

getElemetsByClassName( )

CSS에서 class 선택자는 id 선택자와 다르게 웹 문서 안에서 여러 번 사용 가능하다.

그래서 getElemetsByClassName() 함수는 2개 이상의 웹 요소에 인덱스로 접근한다.

document.getElemetsByClassName("name")[0]
<span class="name">이름</span>

 

getElementById( ) 함수와 querySelector( ) 함수의 차이

getElementById( ) 함수는 단순히 id 선택자를 사용해서 요소에 접근하지만
querySelector( ) 함수는 id 선택자뿐만 아니라 querySelector( #container > ul )처럼 둘 이상의 선택자를 사용해서 요소에 접근 가능하다.
 
  • 글자 속성

- textContent    :   문서 객체 내부 글자를 순수 텍스트 형식으로 가져오도록 변경

- innerHTML     :   문서 객체 내부 글자의 HTML 태그를 반영해 가져오도록 변경

 

  • 내부 글자 변경
<script>
	// 문서 객체 내부의 글자를 변경합니다.
	document.body.textContent = output;

	// HTML 태그를 적용해 내부의 글자를 변경합니다.
	document.body.innerHTML = output;
</script>
  • 스타일 조작

자바스크립트 특수 문자   -   를 식별자에 사용할 수 없으므로 연결된 속성을 대문자로 변경

var header = document.getElementById('header');
header.style.background-color = 'red';	 // X
=> header.style.backgroundColor = 'red'; // O

background-image  →  backgroundImage

background-color   →  backgroundColor

background-sizing  →  backgroundSizing

background-style    →  backgroundStyle

 
  • 문자열을 사용한 스타일 속성 접근

문자열을 사용해 스타일 속성에 접근할 때는 다음 두 가지 방법 모두 사용 가능

document.body.style[ ‘background-color’ ] = ‘red’ ;

document.body.style[ ‘backgroundColor’ ] = ‘red’ ;

 
  • 속성 조작 : 문서 객체의 속성을 조작할 때

setAttribute(속성 이름, 속성 값)    속성 지정

getAttribute(속성 이름)               속성 추출

 

<div id="prod-img">
	<img src="images/coffe.jpg" alt="커피">
</div>
document.querySelector("#prod-img > img").getAttribure("src")
>>> "images/coffee.jpg"

document.querySelector("#prod-img > img").setAttribure("src", "images/bread.jpg")

웹 표준에서 지정하지 않은 속성에 접근할 때는 위의 두 개의 메서드를 사용해야 한다.

data-role은 웹 표준에서 지정하는 속성이 아님

문자열 ‘data-’로 시작하는 것을 사용자 지정 속성이라 함.

반드시 속성조작 메서드를 사용해서 접근해야 함

<body>
	<div data-role=“page”>
		<div data-role=“header”></div>
        </div>
</body>

 

  • img 태그 속성 조작하기

img 태그에 id 속성을 제외한 다른 속성 부여하지 않고, 문서 객체 코드에서 지정함

<head>
    <title>DOM Basic</title>
    <script>
        // 이벤트를 연결합니다.
        window.onload = function () {
            // 변수를 선언합니다.
            var image = document.getElementById('image');

            // 속성을 변경합니다.
            image.src = 'http://placehold.it/300x200';
            image.width = 300;
            image.height = 200;
        };
    </script>
</head>
<body>
    <img id="image" />
</body>

 

  • body 태그 속성 조작하기
<head>
    <title>DOM Basic</title>
    <script>
        // 이벤트를 연결합니다.
        window.onload = function () {
            // 속성을 지정합니다.
            document.body.setAttribute('data-custom', 'value');

            // 속성을 추출합니다.
            var dataCustom = document.body.getAttribute('data-custom');
            alert(dataCustom);
        };
    </script>
</head>
<body>

</body>

 

  • 문서 객체를 사용한 시간 표시
<script>
// 이벤트를 연결합니다.
window.onload = function () {
	// 변수를 선언합니다.
	var clock = document.getElementById('clock');

	// 1초마다 함수를 실행합니다.
	setInterval ( function () {
		var now = new Date();
		clock.innerHTML = now.toString(); }, 1000 ) ;
};
</script>

 

  • 이벤트

키보드를 누르거나 마우스를 클릭하는 것처럼 현상이 발생하는 것

- 마우스 이벤트

- 키보드 이벤트

- HTML 프레임 이벤트

- HTML 입력 양식 이벤트

- 사용자 인터페이스 이벤트

- 구조 변화 이벤트

- 터치 이벤트

 

window.onload = function () { } ;

 

onload                          : 이벤트 속성

on을 제외한 load             : 이벤트 이름 또는 이벤트 타입

이벤트 속성에 넣는 함수    : 이벤트 리스너 또는 이벤트 헨들러

 

 
  • 이벤트 연결

이벤트 모델 : 문서 객체에 이벤트를 연결하는 방식

 

- DOM 레벨 0 : 인라인 이벤트 모델

                     고전 이벤트 모델

- DOM 레벨 2 : 마이크로소프트 인터넷 익스플로러 이벤트 모델

                      표준 이벤트 모델

 

DOM 레벨 0의 이벤트 연결 방식은 널리 사용함. 하지만 이벤트를 중복해서 연결할 수 없다는 단점!

DOM 레벨 2의 이벤트 연결 방식은 이벤트를 중복해서 연결할 수 있지만, 웹 브라우저 종류에 따라 연결하는 방식이 달라 문제가 됨

→ 위의 모든 것들을 jQuery 라이브러리 등을 사용해 극복 가능!

 
 
  • 인라인 이벤트 모델

HTML 태그 내부에 자바스크립트 코드를 넣어 이벤트를 연결하는 방식

- 인라인 이벤트 모델 사용하기
<html>
<head>
    <title>Event Basic</title>
</head>
<body>					// 버튼 태그 내부에 onclick 속성 사용
    <button onclick="alert('click')">버튼</button>
</body>
</html>

- script 태그에 인라인 이벤트 모델 사용하기

<head>
    <title>Inline Event</title>
    <script>
        function buttonClick() {		// script 태그 내부에 함수 선언
            alert('click');
        }
    </script>
</head>
<body>					// 인라인 이벤트 속성 내부에서 해당 함수 실행
    <button onclick="buttonClick()">버튼</button>
</body>

- 고전 이벤트 모델 : 과거에 표준으로 정의되어 많이 사용하던 이벤트 모델

<head>
    <title>Traditional Event</title>
    <script>
        // 이벤트를 연결합니다.
        window.onload = function () {
            // 문서 객체를 선택합니다.
            var button = document.getElementById('button');

            // 이벤트를 연결합니다.
            button.onclick = function () {
                alert('click');
            };
        };
    </script>
</head>
<body>
    <button id="button">버튼</button>
</body>
  • 이벤트 발생 객체

이벤트 리스너 내부에서 this 키워드를 사용하면 이벤트를 발생한 자기 자신을 의미한.

따라서 this 키워드와 textContent 속성을 사용하면 자기 자신의 글자를 변경한다.

<body>
    <button id="button">버튼 - </button>
    <script>
        // 이벤트를 연결합니다.
        document.getElementById('button').onclick = function () {
            this.textContent = this.textContent + '★';
        };
    </script>
</body>
  • 이벤트 사용

이벤트 객체를 사용하여 이벤트와 관련된 정보 알아내기

<script>
        window.onload = function (event) {
            alert(event);
        };
</script>
  • 기본 이벤트(특정 태그가 가진 기본적인 이벤트) 제거

제출 버튼을 누를 때 입력 양식에서 기재 하지 않은 경우 기본 이벤트를 제거해야 함

<script>
        // 이벤트를 연결합니다.
        window.onload = function () {
            // 문서 객체를 선택합니다.
            var button = document.getElementById('button');
            // 이벤트를 연결합니다.
            button.onclick = function () {
                // 기본 이벤트를 제거합니다.
                return false;
            };
        };
</script>

클래스 값이 abc인 모든 요소를 빨간색으로 만듦

<!doctype html>
<html lang="ko">
  <head>
    <meta charset="utf-8">
    <title>JavaScript</title>
  </head>
  <body>
    <p class="abc">Lorem Ipsum Dolor</p>
    <p class="abc">Lorem Ipsum Dolor</p>
    <p class="abc">Lorem Ipsum Dolor</p>
    <script>
      var jb = document.querySelectorAll( '.abc' );
      for ( var i = 0; i < jb.length; i++ ) {		=> 배열 형태로 저장
        jb[i].style.color = 'red';
      }
    </script>
  </body>
</html>

 

DOM에 요소 추가하기

  함수 설명
1 createElement( 요소 노드 ) 새 요소 노드를 만듭니다.
2-1 createTextNode( 텍스트 ) 텍스트 내용이 있을 경우 텍스트 노드를 만듭니다.
appendChild( 자식 노드 ) 텍스트 노드를 요소 노드에 마지막 자식 노드로 추가합니다.
2-2 createAttribute( 속성 이름 ) 요소에 속성이 있을 경우 속성 노드를 만듭니다.
setAttribute( 속성 노드 ) 속성 노드를 요소 노드에 연결합니다.
3 appendChild( )  새로 만든 요소 노드를 부모 노드에 추가합니다.

 

// <p> 태그 요소 노드 생성
var newP = document.createElement("p")

// 텍스트 노드 만들기
var newText = document.createTextNode("주문이 완료되었습니다.")

// newText를 newP 노드를 자식 노드로 추가
newP.appendChild(newText)

// newP를 body 노드의 자식 노드로 추가
document.body.appendChild(newP)

// <p> 태그에 class="accent" 속성 추가하여 속성 노드 만들기
var attr = document.createAttribute("class")
attr.value = "accent"

// 속성 노드를 p 노드와 연결
newP.setAttribute(attr)

 

createAttribute( ) 함수로 속성 노드를 만들고 "accent" 값을 넣은 뒤 setAttribute( ) 함수를 사용해 p 노드에 연결할 수 있다. 하지만 setAttribute( ) 함수를 사용하여 더 간단히 속성을 추가할 수 있다.

var newP = document.createElement("p")
var newText = document.createTextNode("완료!")
newP.appendChild(newText)
document.body.appendChlid(newP)
<p>완료!</p>
newP.setAttribute("class", "accent")

 

DOM 트리를 활용해 원하는 노드 다루기

함수 설명
hasChildNodes( ) 자식 노드 확인하기 (자식 노드가 있다면 true를 없다면 false 반환)
childNodes( ) 자식 노드 접근하기
insertBefore( 새로 추가할 자식 노드, 기준 노드 위치) 원하는 위치에 노드 앞에 삽입하기
removeChild( ) 특정 노드 삭제하기
<div id="container">
    <h1>참석자 명단</h1>
    <div id="nameList">
    	<p>홍길동 <span class="del">X</span></p>
    	<p>백두산 <span class="del">X</span></p>
    	<p>도레미 <span class="del">X</span></p>
    </div>
</div>
// p 노드 중 첫 번째 p 노드에 자식 노드가 있는지 확인
document.querySelector("p")[0]hasChildNodes( ) // 자식 노드가 있다면 true 반환

// #nameList 요소의 자식 요소에 접근
document.querySelector("#nameList").childNodes
// <div> 태그 다음의 줄 바꿈, <p> 태그 사이의 줄 바꿈
// 그리고 </div> 태그 앞의 줄 바꿈을 빈 텍스트 노드로 인식하기 때문에 7개 요소 출력
>> NodeList(7) [text, p, text, p, text, p, text]

// 요소에만 접근하기 위해서는 children 속성을 사용한다
document.querySelector("#nameList").children
>> HTMLCollenction(3) [p, p, p]

// 첫 번째 자식 노드 앞에 새로운 자식 노드 추가
nameList.insertBefore(nameList.children[2], nameList.children[0])

// 부모 노드에서 자식 노드 삭제
// 첫 번째 <spam class-"de">X</span> 요소 삭제
var firstDel = document.querySelectorAll(".del")[0] // 첫 번째 X
var firstP = document.querySelectorAll("p")[0] // 첫 번째 p 요소
firstP.removeChild(firstDel) // 첫 번째 p 요소에 있는 첫 번째 X 삭제

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

[JS] 자바스크립트 함수 표현식  (0) 2022.03.16
[JS] VSCode에서 JS 콘솔 실행하기 (node.js 설치)  (0) 2022.03.12
[JS] let과 constant 변수  (0) 2022.03.12
[JS] JQuery 라이브러리  (0) 2022.02.11
[JS] 자바스크립트 기본 문법  (0) 2022.02.11

댓글