JavaScript - 문서 객체 모델(DOM)

하쮸·2025년 6월 29일

JavaScript

목록 보기
4/4

1. 문서 객체 모델.

  • DOM(Document Object Model) : 문서 객체 모델.
  • DOM은 자바스크립트 프로그래밍에서 매우 중요한 개념.

1-1. 문서 객체 모델이란?

  • 웹에서 자바스크립트를 사용하는 이유
    어떤 조건에 맞거나 사용자의 동작이 있을 때 웹 문서 전체 or 일부분이 동적으로 반응하게 하려고.

    • 반응하게 하려면 웹 문서의 모든 요소를 따로 제어할 수 있어야됨.
  • 많은 요소를 사용한 웹 문서라면 요소 사이의 포함 관계도 알아야함.

  • 이러한 모든 정보 요소를 자바스크립트로 가져와서 프로그래밍할 때 사용함.

    • 이때 알아야할 개념이 DOM(Document Object Model, 문서 객체 모델)임.

문서 객체 모델(DOM)의 정의.

  • 자바스크립트를 이용하여 웹 문서에 접근하고 제어할 수 있도록 객체를 사용해 웹 문서를 체계적으로 정리하는 방법.
  • HTML 문서 구조를 객체로 표현한 것.
  • DOM은 웹 문서를 하나의 객체로 정의하고 웹 문서를 이루는 텍스트, 이미지 등의 모든 요소도 각각 객체로 정의함.
    • 즉, DOM은 웹 문서와 그 안의 모든 요소를 객체로 인식하고 처리함.
  • 문서 구조란?
    • HTML 문서에는 <body>, <p> 등 여러 태그가 문서의 구조를 이루고 있음.
      여러가지 HTML 요소의 계층을 반영해서 만든 객체가 바로 DOM.
    • HTML 문서를 객체로 표현하면 JavaScript와 같은 스크립트 및 프로그래밍 언어가 웹페이지에 접근할 수 있음.
      즉, DOMHTML로 구성된 웹 페이지스크립트 및 프로그래밍 언어연결시켜주는 역할.

  • 프로그래밍 언어마다 DOM에 접근하는 방법이 다름.
    • 자바스크립트에서는 일반적으로 HTML 요소의 id 선택자를 사용하는 document.getElementByld("#id") 메서드가 있음.
    • 리액트에서는 useRef() 함수를 사용해서 DOM에 접근할 수 있음.

1-2. DOM 계층구조.

  • DOM은 HTML 문서 구조의 계층을 표현한 객체.
    • 이때 DOM의 계층은 트리 자료 구조로 구축됨.
      • 여기서 트리 자료 구조는 하나의 최상위 노드(Node)에서 다른 자식 노드들이 뻗어나가는 구조.

  • 위 이미지처럼 document 노드가 최상위 노드로서 맨 위에 있고 이어서 element, text, attribute 노드가 나오는 계층적 구조.

1-2-1. DOM 트리.

  • DOM은 웹 문서의 요소를 부모 요소와 자식 요소로 구분함.
<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>DOM Tree 알아보기</title>
</head>
<body>
  <h1>Do it!</h1>
  <img src="images/doit.jpg" alt="공부하는 이미지">
</body>
</html>

↓ HTML 요소의 계층 관계

  • html 요소는 head, body의 부모요소.
    • body 요소는 h1, img의 부모 요소가 됨.
  • DOM은 문서안의 요소뿐만 아니라 각 요소에서 사용한 내용과 속성도 자식으로 나타냄.
    • h1 요소의 내용인 'do it'은 h1의 자식이 되고
      src, alt 속성은 img 요소의 자식이 되는 것.
  • DOM 트리에서 가지가 갈라져서 나간 항목을 노드(node).
    • DOM 트리의 시작 부분인 html 노드를 루트(rood) 노드.
      루트 노드를 시작으로 해서 웹 문서에서 사용한 요소는 계층 구조를 이룸.
    • 부모(parent) 노드에는 자식(child) 노드가 있고, 부모 노드가 같은 형제(sibling) 노드도 있음.

1-2-2. DOM을 구성하는 기본 원칙.

  • 모든 HTML 태그요소(element) 노드임.
  • HTML 태그에서 사용하는 텍스트 내용은 자식 노드인 텍스트(text) 노드임.
  • HTML 태그에 있는 속성은 자식 노드인 속성(attribute) 노드임.
  • 주석은 주석(comment) 노드임.
root element : html
    └── element : head
    |       ├── element : meta
    |       │   └── attribute : charset = "UTF-8"
    |       └── element : title
    |           └── text : "DOM Tree 알아보기"
    └── attribute : lang = "ko"
    └── element : body
            ├── element : h1
            │   └── text : "Do it!"
            └── element : img
                ├── attribute : src = "images/doit.jpg"
                └── attribute : alt = "공부하는 이미지"

1-3. DOM이 생성되는 순서.

  • HTML 웹 페이지는 HTML 파서(Parser)에 의해 DOM으로 변환됨.

    • 이때 파서가 <script> 태그를 만나게 되면 파서는 DOM 생성을 잠시 멈추고 자바스크립트 엔진이 script에 정의된 파일 및 코드를 실행함.
      • 이후 스크립트 실행이 완료되면 다시 HTML 파서가 DOM 생성을 다시 시작.
  • 브라우저는 동기적으로 HTMLJavaScript처리하기 때문에 <script> 태그의 위치에 따라 DOM 생성이 느려질 수 있음.

    • 따라서 <script> 태그는 HTML 문서 제일 하단(</body>)직전에 넣는 것이 좋음.
      • 그래야 DOM 생성이 지연되지 않고 스크립트가 DOM 요소를 안전하게 조작할 수 있음.

2. DOM 요소에 접근하고 속성 가져오기.

  • 자바스크립트를 사용해서 DOM에 접근하기.

2-1. 선택자로 DOM에 접근.

  • CSS에서는 class, id, 태그 등의 스타일을 각각 구별해서 정의해야함.
    • 이때 class, id, 태그 등선택자(selector)라고 하는데
      선택자를 사용해서 DOM에 접근하기.

2-1-1. id 선택자로 접근.

  • HTML 태그의 id 속성은 HTML 요소가 문서 안에서 중복되지 않도록 사용하는 CSS 선택자임.

  • getElementById() 메서드를 이용하면 특정한 id가 포함된 DOM 요소에 접근할 수 있음.

요소명.getElementById("id명")

2-1-2. class 값으로 접근.

  • getElementsByClassName() 메서드는 지정한 class 선택자 이름이 들어 있는 DOM 요소에 접근함.
요소명.getElementsByClassName("class명")
  • class 선택자는 웹 문서 안의 여러 요소에서 사용할 수 있으므로
    getElementsByClassName() 메서드의 반환값이 2개 이상일 수 있음.

    • 그래서 메서드 이름 Elements가 붙은거임.
  • getElementsByClassName()을 사용하면 클래스 이름이 같은 DOM 요소들이 HTMLCollection 객체로 저장됨.

    • HTMLCollection 객체배열과 비슷하고 배열처럼 사용할 수 있지만 배열은 아님.

2-1-3. 태그 이름으로 접근.

  • class나 id를 지정하지 않은 DOM 요소에 접근하려면 태그를 이용함.

  • getElementsByTagName()메서드는 지정한 태그명을 사용한 DOM 요소에 접근할 수 있음.

요소명.getElementsByTagName("태그명")
  • 웹 문서 안에서 같은 태그를 사용하는 요소가 2개 이상일 수 있으므로 getElementsByTagName() 메서드가 반환하는 값도 HTMLCollection 형태로 저장됨.

2-2. 다양한 방법으로 DOM에 접근.

  • getElementById(), getElementsByClassName(), getElementsByTagName() 메서드의 반환값은 HTMLCollection 객체임.
    • 여기에는 HTML 요소(p나 a같은 형태)만 저장됨.
  • DOM 트리의 텍스트, 속성 노드까지 자유롭게 제어하려면 querySelector(), querySelectorAll()메서드를 사용해야됨.
    • id 선택자처럼 반환값이 하나라면 querySelector()사용.
    • class 선택자나 태그 이름을 사용하여 여러 값이 한꺼번에 반환될 경우에는 querySelectorAll()사용.
노드.querySelector(선택자)
노드.querySelectorAll(선택자 or 태그)
  • querySelector(), querySelectorAll() 메서드에서 선택자를 표시할 때 id 이름 앞에는 해시기호(#)를 붙이고
    class 이름 앞에는 마침표(.)를 붙임.
    • 태그는 기호 없이 태그명만 쓰면됨.
  • querySelector()메서드에서 class 이름으로 접근할 때는 class 이름을 사용한 여러 요소 중에서 첫 번째 요소만 반환함.
  • querySelector(), querySelectorAll()의 반환값은 노드(node)이거나 노드 리스트(node list)임.

2-2. innerText, innerHTML.

  • innerText, innerHTML 프로퍼티를 이용해서 자바스크립트에서 웹 요소의 내용도 수정할 수 있음.
    • innerText : 텍스트 내용을 표시.
    • innerHTML : HTML 태그까지 반영하여 표시함.
요소명.innerText = 내용
요소명.innerHTML = 내용

2-3. getAttribute(), setAttribute().

  • 웹 요소를 문서에 삽입할 때 태그 속성을 함께 사용하면 DOM 트리에 속성 노드가 추가되면서 속성값이 저장됨.
    • 속성에 접근하려면 getAttribute() 메서드 사용.
    • 접근한 속성의 값을 바꾸려면 setAttribute() 메서드 사용.
// 속성 가져오기
getAttribute("속성명")

// Ex)
<script>
  function displaySrc() {
  var cup = document.querySelector("#cup");					// id="cup"인 요소에 접근.
  alert("이미지 소스 : " + cup.getAttribute("src"));			// cup 속성을 알침 창에 표시.
}	
</script>

---------------------------------------------------------------------------

// setAttribute()를 사용하면 원하는 속성값으로 지정할 수 있음.
// 아직 해당 속성이 없다면 속성과 속성값을 새로 추가함.
setAttribute("속성명", "값")

// Ex)
<script>
  var cup = document.querySelector("#cup");
var smallPics = document.querySelectorAll(".small");

for(let i = 0; i < smallPics.length; i++) {
  smallPics[i].addEventListener("click", changePic);		// 반복문으로 각 썸네일에 클릭 이벤트 리스너 등록 → changePic 함수 연결
}

function changePic() {
  var newPic = this.src;									// 클릭한 이미지의 src값 추출
  cup.setAttribute("src", newPic);							// 메인 이미지의 src를 그 값으로 교체
}			
</script>

3. DOM에서 이벤트 처리.

  • 웹 문서에서 이벤트가 발생하면 이벤트 처리기(event handler)를 연결해야함.
  • HTML 태그에서 이벤트 처리기를 연결할 수도 있지만 태그와 스크립트 소스가 섞여 있어서 복잡한 프로그램에는 적합하지 않음.
    • DOM에서 이벤트 처리기를 연결하면 HTML 태그와 스크립트 소스를 분리할 수 있음.

3-1. DOM 요소에 함수 직접 연결.

  • 이벤트 처리기 함수가 간단하다면 DOM 요소에 직접 연결할 수 있음.
<body>
  <div id="container">
    <img src="images/cup-1.png" id="cup">		
  </div>
  <script>
	var cup = document.querySelector("#cup");  // id = cup인 요소를 가져옴
    cup.onclick = function(){
    	alert("이미지를 클릭했습니다");
    }
  </script>
</body>

3-2. 함수 이름을 사용해서 연결.

  • 이벤트가 발생했을 때 실행할 함수를 따로 정의해 놓았다면 함수 이름을 사용해 연결할 수 있음
    • 이 경우 함수 이름 뒤에 괄호(())를 추가하지 않음.
<body>
  <div id="container">
    <img src="images/cup-1.png" id="cup">		
  </div>

  <!-- 함수 이름을 사용해 연결. -->
	<script>
	var cup = document.querySelector("#cup");   // id = cup인 요소를 가져옴
    cup.onclick = changePic;                    

    function changePic() {
      cup.src = "images/cup-2.png";
	}
	</script>
</body>

3-3. DOM의 event 객체.

  • DOM에는 이벤트 정보를 저장하는 event 객체가 있음.
    • 해당 객체에는 웹 문서에서 이벤트가 발생한 요소가 무엇인지, 어떤 이벤트가 발생했는지 등의 정보가 들어 있음.
<body>
	<div id="container">
    	<img src="images/cup-1.png" id="cup">		
	</div>	

    <!-- DOM의 event 객체 -->
    <script>
      var cup = document.querySelector("#cup");			// id = cup인 요소를 가져옴
      cup.onclick = function(event) {						
      alert("이벤트 유형: " + event.type + ", 이벤트 발생 위치 : " + event.pageX + "," + event.pageY);	
      }
    </script>
</body>

event 객체의 프로퍼티와 메서드

구분 이름 설명
프로퍼티 altKey - 이벤트가 발생할 때 alt 키를 눌렀는 지 여부를 boolean 값으로 반환함.
button - 마우스에서 누른 버튼의 키 값을 반환함.
charCode - keypress 이벤트가 발생할 때 어떤 키를 눌렀는지 유니코드 값으로 반환함.
clientX - 이벤트가 발생한 가로 위치를 반환함.
clientY - 이벤트가 발생한 세로 위치를 반환함.
ctrlKey - 이벤트가 발생했을 때 Ctrl 를 눌렀는지 여부를 boolean 값으로 반환함.
pageX - 현재 문서 기준으로 이벤트가 발생한 가로 위치를 반환함.
pageY - 현재 문서 기준으로 이벤트가 발생한 세로 위치를 반환함.
screenX - 현재 화면 기준으로 이벤트가 발생한 가로 위치를 반환함.
screenY - 현재 화면을 기준으로 이벤트가 발생한 세로 위치를 반환함.
shiftKey - 이벤트가 발생할 때 shift 키를 눌렀는지 여부를 boolean 값으로 반환함.
target - 이벤트가 최초로 발생한 대상을 반환함.
timeStamp - 이벤트가 발생한 시간을 반환함.
type - 발생한 이벤트 이름을 반환함.
which - 키보드와 관련된 이벤트가 발생할 때 키의 유니코드 값을 반환함.
메서드 preventDefault() - 이벤트를 취소할 수 있는 경우에 취소함.
  • event 객체에는 이벤트 정보만 들어 있음.
    • 만약 이벤트가 발생한 대상에 접근하려면 이벤트 처리기에서 예약어 this를 사용해야함.
<body>
	<div id="container">
		<img src="images/cup-1.png" id="cup">	
	</div>
  
	<script>
		var cup = document.getElementById("cup");
		cup.onclick = function(event) {
      		// 클릭한 이미의 파일 경로를 알기 위해 this.src로 작성.
			alert("클릭한 이미지 파일 : " + this.src);		
		}
	</script>
</body>


4. 참고.

profile
Every cloud has a silver lining.

0개의 댓글