본문 바로가기
📌 Front End/└ JavaScript

[JavaScript] 자바스크립트 문서 객체 모델(DOM) - DOM Tree, DOM API, DOM 노드 접근, DOM 노드 탐색, DOM 노드 조작, DOM 이벤트 처리

by 쫄리_ 2024. 6. 16.
728x90
반응형

문서 객체 모델 DOM (Document Object Model)

DOM 이란 Document Object Model의 약자입니다. 번역하자면 문서 객체 모델인데요.

여기서의 문서는 HTML 문서를 말한다.

 

브라우저는 웹 문서를 로드한 후, 파싱하여 DOM을 생성한다.
DOM은 모든 요소, 속성, 텍스트를 객체로 만들어 이 객체들을 부자 관계에 따라 트리 구조로 구성한 것을 의미한다.
정적인 웹페이지를 변경하는 유일한 방법은 DOM을 변경하는 것이며, 이 때 필요한 것이 DOM API이다.


DOM Tree 구성요소

  • 문서 노드(Document Node)  ➡️  최상위 트리이자 접근의 시작점이다.
  • 요소 노드(Element Node)  ➡️  HTML 요소를 표현한다.
  • 속성 노드(Attribute Node)  ➡️  HTML 요소의 속성을 표현한다.
  • 텍스트 노드(Text Node)  ➡️  HTML 요소의 텍스트를 표현한다. 자식을 가질 수 없다.

  ✔️ <html> = document.documentElement

  ✔️ <body> = document.body

  ✔️ <head> = document.head

<html>
<head>
    <title>DOM 공부하기</title>
</head>
<body>
    <h1>DOM을 알아봅시다</h1>
    <p>DOM 구조는 트리 모양입니다.</p>
</body>
</html>


DOM API

DOM을 통해 웹페이지를 조작하려면 다음에 맞게 API를 사용한다.

  • 조작하고자하는 요소를 선택 또는 탐색한다.
  • 선택된 요소의 콘텐츠 또는 어트리뷰트를 조작한다.

 

✍️ DOM 핵심 API

유형 메서드명
순회 childNodes, firstChild, lastChild, nextSibling, previousSibling
선택 getElementById() , getElementsByTagName()
getElementsByName(), getElementsByClassName()
querySelector(), querySelectorAll()
생성 / 추가 / 삭제 createElement(), createTextNode(), appendChild(), removeChild()
createAttribute() , setAttribute(), getAttribute()
내용 저장 / 조회 innerHTML, innerText, value

DOM 노드 접근/선택

메서드명 설명
document.getElementById("id명") * id 접근 / 하나의 요소 노드 선택
해당 아이디를 가진 요소를 선택해서 
첫 번째 요소 하나를 객체 리턴
document.getElementsByClassName("class명") * class 접근 / 여러 개의 요소 노드 선택
해당 클래스를 가진 요소들을 선택해서 
요소들을 배열로 리턴

공백을 사용하면 여러 개의 class를 지정
HTMLCollection 형태로 반환

document.querySelector("cssSelector") * css 선택자 접근 / 하나의 요소 노드 선택
CSS 선택자 문법으로 선택자에 해당하는 
첫 번째 요소 하나를 객체 리턴

querySelector("선택자");
querySelector("#아이디명");
querySelector(".클래스명");
querySelector("태그명");
document.querySelectorAll("cssSelector") * css 선택자 접근 / 여러 개의 요소 노드 선택
CSS 선택자 문법으로 선택자에 해당하는 
요소들을 배열로 리턴

querySelectorAll("선택자");
querySelectorAll("#아이디명");
querySelectorAll(".클래스명");
querySelectorAll("태그명");

NodeList 형태로 반환
document.getElementsByTagName("tag명") * 태그명 접근
해당 태그 요소들을 선택해서
요소들을 배열로  리턴

HTMLCollection 형태로 반환

DOM 노드(Node) / 엘리먼트(Element) 탐색

  • Node : 태그(요소 노드), 속성, 주석, 내용(텍스트 노드)를 모두 표현
  • Element : Node의 하위 개념으로 요소 노드만을 표현한다. 즉, 속성, 주석, 내용은 해당하지 않는다.

📝 노드(Node) 탐색

유형 종류 설명
부모 Node 탐색 요소.parentNode 요소의 부모 노드를 탐색해서 반환
자식 Node 탐색 요소.childNodes 요소의 자식 노드를 모두 반환
NodeList 형태
요소.firstChild 첫 번째 자식 노드 탐색해서 반환
요소.lastChide 마지막 자식 노드를 탐색해서 반환
요소.childNodes[인덱스] 인덱스 n번째 자식 노드를 탐색해서 반환
형제 Node 탐색 요소.previousSibling 요소의 이전 형제 노드를 반환
요소.nextSibling 요소의 다음 형제 노드를 반환

 

 

📝 엘리먼트(Element) 탐색

종류 설명
children 자식 요소만 모두 선택
parentElement 부모 요소 선택
firstElementChild 첫 번째 자식 요소 선택
lastElementChild 마지막 자식 요소 선택
previousSibling 이전 형제 요소 선택
nextSibling 다음 형제 요소 선택

 


DOM 노드 조작

📝 HTML 요소 생성/삽입/삭제

         innerHTML을 사용하지 않고, 새로운 콘텐츠를 추가하는 방법

메서드명 설명
document.createElement("태그명") html 요소 생성
태그이름을 인자로 전달하여 태그 요소를 생성

ex.
let div = document.createElement('div');
document.createTextNode("텍스트") 텍스트를 인자로 전달하여
텍스트 노드를 생성

ex.
let text = document.createTextNode('안녕?');
추가할 노드의 부모노드.appendChild(추가할 노드) html 요소 추가
해당 태그의 자식요소로 삽입하겠다.
추가할 노드의 부모 노드에 먼저 접근해야 한다.

ex.
// 텍스트 노드를 <div> 노드의 자식 노드로 추가
div.appendChild(text);

// '<div>안녕?</div>' 노드를 문서의 body 파트에 붙여 넣는다.
document.body.append(div);
삭제할 노드의 부모노드.removeChild(삭제할 노드) 인자로 전달한 노드를 DOM 트리에 제거
먼저 부모 노드에 접근해서 자식 노드를 삭제해야 한다.

 

 

사용예시

const newBlock = document.createElement("div");	// html 요소 생성
newBlock.innerText = "shape";	// html 요소 내용 수정
newBlock.setAttribute("class","box1");	// html 요소에 attribute 설정하기
newBlcok.style.background = "#000";	// css style background 적용
document.body.appendChild(newBox1);	// html 요소 추가 (body의 하부 요소로 추가)

 


📝 HTML 콘텐츠 조작

유형 메서드명 설명
내용
(Content)
요소.innerText
요소.innerText = "값";
요소 안의 text 값 내용 조회/수정 (텍스트 내용)
(내용을 덮어쓰는 방식)
(부모요소를 잡으면 자식 것까지 다 가져온다)
요소.innerHtml
요소.innerHtml = "<i>값</i>";
요소 내용 조회/수정 (텍스트 내용, HTML 태그 반영)
(부모요소를 잡으면 자식 것까지 다 가져온다)
 요소의 속성
(Attribute)
요소.getAttribute("속성명");
요소.setAttribute("속성명", "값");
요소.removeAttribute("속성명");
1. 요소의 특정 속성의 속성 값 반환

2. 요소에 속성/값 설정,수정
    (기존 정의된 style 지우고, 새로운 속성으로 덮어쓴다.)

3. 요소의 특정 속성 삭제
CSS 스타일
(Style)
요소.style
요소.style.스타일속성명 = "값";
1. inline으로 정의된 style 속성만 가져온다.
2. 기존 정의 된 style에서 새로운 속성 추가

* 카멜표기법 사용
background-color → backgroundColor
list-style-type → listStyleType

ex.
<p>권소현</p>
const text = document.querySelector("p");
text.style.color = "hotpink";
요소.style.cssText  = "값"; 기존 정의된 style 지우고, 새로운 속성으로 덮어쓴다.

ex.
const text = document.querySelector("p");
text.style.cssText = 
  "padding: 20px 0; color: hotpink; background-color: beige";
getComputedStyle(요소); inline으로 정의된 style 속성 뿐 아니라 
CSS 파일 내 stlye 속성도 함께 가져온다.

ex.
<span style='padding: 20px; color: hotpink;'>
     권소현
</span>
const text = document.querySelector("span");
print.innerText +=  getComputedStyle(text).color;

 


DOM 이벤트 처리

웹페이지에서 마우스 클릭, 키보드를 입력, 특정요소에 포커스가 이동될 때 어떤 사건을 발생

  • DOM Level 0 ➡️ 인라인 이벤트 핸들러 : HTML 요소의 이벤트 처리기 속성에 설정
  • DOM Level 0 ➡️ 이벤트 핸들러 프로퍼티 : DOM 요소 객체의 이벤트 처리기 프로퍼티에 설정
  • DOM Level 2 ➡️ addEventListner() 메서드

 

this 키워드

이벤트 함수 내부에서 this 키워드를 사용하면 이벤트가 발생한 요소 노드를 바로 가리킬 수 있다.

단, 화살표 함수일 때는 이벤트 객체의 target 속성으로 참조해야 한다.


1. 인라인 이벤트 핸들러

HTML 태그의 속성(attribute)에 이벤트 속성을 추가하는 방법입니다. 

이벤트명 앞에 on 접두사를 붙여 사용합니다. 자바스크립트 코드와 HTML이 혼합되기 때문에 비 권장되는 방법입니다.

* HTML 문서를 읽어들일 때 이벤트 처리기도 함께 설정하기 때문에 설정하기 쉬움

<!-- body 부분 -->
<button onclick="test()">버튼</button>

<!-- script 부분 -->
<script>
	function test() {  //click 이벤트 발생시 처리할 함수 등록
		console.log("클릭!!");
	}
</script>

2. 이벤트 핸들러 프로퍼티

HTML과 분리하여 스크립트 코드에서 DOM 객체의 프로퍼티(property)를 이용하는 방법입니다. 

대상 DOM 요소에 on 접두사를 붙인 이벤트명으로 이벤트 핸들러 프로퍼티를 설정하고 이벤트 발생시 처리할 함수를 등록합니다. 

* HTML과 자바스크립트를 분리해서 작성 가능

 

📝 이벤트 핸들러 형태

요소.on이벤트명 = 익명함수;

 

사용예시

var card = document.querySelector("#card");
card.onclick = function(event){
	// 이벤트가 발생한 대상 객체에 접근하려면 이벤트 처리기에서 예약어 this를 사용 
	alert("클릭한 이미지 파일 : " + this.src);
}

3. addEventListner() 메서드

addEventListener() 메소드 방식 (표준 이벤트 모델)입니다. 

addEventListener() 메소드를 이용하여 대상 DOM 요소에 이벤트를 설정하고 

해당 이벤트가 발생했을 때 실행될 이벤트 핸들러를 등록합니다. 

이는 더 현대적인 방식으로서, 앞선 두 가지 방식보다 이점을 가지고 있습니다. 

인라인 이벤트 핸들러 방식, 이벤트 핸들러 프로퍼티 방식은 각 요소에 이벤트 타입별로 하나의 이벤트 핸들러만 연결할 수 있는 반면, 

addEventListener() 메소드 방식은 여러 개의 이벤트 핸들러를 연결할 수 있습니다. 

또한, 이전에 추가한 이벤트 핸들러를 제거하는 removeEventListener()라는 대응 관계에 있는 함수가 제공됩니다.

 

📝 addEventListner() 형태

요소.addEventListener('이벤트타입', 익명함수);

 

사용예시

document.querySelector("#out")("mouseover", function(){
        // 이벤트를 발생시켰을 시 실행할 동작 (이것도 콜백함수)
        this.style.backgroundColor = "red";
});

 


📝 이벤트 타입별 주요 이벤트 (리소스,마우스,키보드,폼,포커스,UI)

이벤트 취소

preventDefault() 메서드를 사용하면 태그에 기본으로 연결된 이벤트를 취소할 수 있다.

분류 이벤트명 발생 타이밍 주된 대상 요소


리소스

load
DOMContentLoaded 이벤트가 발생한 이후, 
모든 리소스(이미지, 폰트 등)의 로딩이 완료되었을 때
body, img
unload 다른 페이지로 이동할 때
리소스가 언로드 될 때
(주로 새로운 웹페이지를 요청한 경우)
body
abort 리소스 로딩이 중단되었을 때 img
error
리소스 로딩이 실패했을 때 img
마우스 click 마우스 버튼을 클릭했을 때  
dblclick 마우스 버튼을 더블 클릭했을 때  
mousedown 마우스 버튼을 누르고 있을 때  
mouseup 누르고 있던 마우스 버튼을 뗄 때  
mousemove 마우스를 움직일 때
(터치스크린에서 동작 x)
 
mouseover 마우스를 요소 위로 움직였을 때
(터치스크린에서 동작 x)
 
mouseout 마우스를 요소 밖으로 움직였을 때
(터치스크린에서 동작 x)
 
contextmenu context menu가 표시되기 전 body
키보드 keydown 모든 키를 눌렀을 때 발생  
keyup 누르고 있던 키를 놓았을 때 한번만 발생  
keypress 문자 키를 눌렀을 때 연속적으로 발생  

input
input(text, checkbox, radio), select, textarea 요소의 
값이 입력되었을 때
 
change input(text, checkbox, radio), select, textarea 요소의 
값이 변경되었을 때
input(text), select
submit form 요소 내의 submit 버튼을 클릭했을 때 form
reset form 요소 내의 reset 버튼을 클릭했을 때 form
포커스

focus HTML 요소가 포커스를 받았을 때 (버블링 x)  
blur HTML 요소가 포커스를 잃었을 때 (버블링 x)  
focusin HTML 요소가 포커스를 받았을 때 (버블링 o)  
focusout HTML 요소가 포커스를 잃었을 때 (버블링 o)  
UI resize 브라우저 윈도우(window)의 크기를 
리사이즈할 때 연속적으로 발생(window객체만)
 
scroll 웹페이지(document) 또는 
HTML 요소를 스크롤할 때 연속적으로 발생
body

 

 

728x90
반응형