문서 객체 모델(Document Object Model)
웹 문서를 객체로 다루는 시스템으로 HTML, XML 문서의 프로그래밍 인터페이스이다.
문서의 구조화된 표현을 제공
하며
프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공해
그들이 문서구조, 스타일, 내용 등을 변경할 수 있게 돕는다.
⇒ DOM은HTML을 위한 API
이면서, HTML을탐색
할 수 있고구조를 바꿀 수
있다.
⇒ HTML 문서의 계층적 구조와 정보를 표현하며 이를 제어할 수 있는 API, 즉 프로퍼티와 메서드를 제공하는 트리 자료구조이다.
웹 페이지의 객체 지향 표현이며, 자바스크립트와 같은 스크립팅 언어를 이용해 DOM을 수정할 수 있다.
⇒ JavaScript는 브라우저가 읽고어떤 작업을 할 수 있는 언어
인데,
DOM은 이 작업이 이루어지는장소
이다.
⇒ 우리가JS로 하는 것
이라고 생각하는 것은DOM API
이다.
HTML 요소(엘리먼트) 는 HTML 문서를 구성하는 개별적인 요소를 의미하는데,
이 요소들이 렌더링 엔진에 의해 파싱되어 DOM을 구성하는 요소 노드 객체
로 변환된다.
⇒ HTML요소의 어트리뷰트는 어트리뷰트 노드로, 텍스트콘텐츠는 텍스트 노드로 변환
⇒ body
안에 h1
요소의 내용
도 h1의 자식 노드
가 된다.
HTML요소 간 중첩 관계(포함 관계)에 의해 계층적인 부자 관계가 형성되는데,
이러한 부자 관계를 반영해 HTML 요소를 객체화한 모든 노드 객체들을 트리 자료 구조로 구성한다.
노드 객체는 종류가 있고 상속 구조를 갖는데, 총 12개의 종류가 있다.
문서 노드
(Document node) : 문서 전체를 나타내는 노드
DOM 트리의 최상위에 존재하는 루트 노드로서 document 객체를 가르키고, window.document 또는 document로 참조할 수 있다.
⇒ DOM 트리의 노드들에 접근하기 위한 진입점 역할을 담당한다.
⇒ 요소, 어트리뷰트, 텍스트 노드에 접근하려면 문서 노드를 통해야 한다.
요소 노드
(Element node) : 속성 노드를 가질 수 있는 유일한 노드
HTML 요소를 가리키는 객체로
HTML 요소 간의 중첩에 의해 부자관계를 가지며, 이 부자관계를 통해 정보를 구조화한다.
⇒ 문서의 구조를 표현한다고 할 수 있다.
속성 노드
(Attribute node) : 요소 노드에 관한 정보를 가지고 있다.
HTML 요소의 어트리뷰트를 가리키는 객체로 어트리뷰트가 지정된 HTML 요소의 요소 노드와 연결되어 있다.
⇒ 어트리뷰트 노드는 부모 노드와 연결되어 있지 않고 요소 노드에만 연결되어 있기 때문에, 요소 노드의 형제 노드가 아니다.
⇒ 어트리뷰트를 참조하거나 변경하려면 먼저 요소 노드에 접근해야 한다.
텍스트 노드
(Text node)
HTML 요소의 텍스트를 가리키는 객체로, 요소 노드가 문서의 구조를 표현한다면 텍스트 노드는 문서의 정보를 표현한다고 할 수 있다.
⇒ 요소 노드의 자식 노드이지만 자식노드를 가질 수 없는 리프 노드이다.
⇒ DOM 트리의 최종단인데, 텍스트 노드에 접근하려면 부모 노드인 요소 노드에 접근해야 한다.
노드들의 계층 구조로 이루어진다.
부모 노드와 자식 노드로 구성되어 노드 간의 계층적 구조를 표현하는 비선형 자료구조를 말한다.
노드
: DOM 트리에서 가지가 갈라져 나가는 부분루트 노드
: DOM 트리의 최상위 노드(부모 노드가 없고, 0개 이상의 자식 노드를 가짐)리프 노드
: 자식 노드가 없는 노드형제 노드
: 같은 부모 노드를 가진 노드들웹 문서에 있는 이미지나 테스트, 표 등 특정 요소를 찾아가는 것을
웹 요소에 접근한다
라고 하는데, 이렇게 접근하면 해당 요소의 내용이나 값을 가져오거나 수정할 수 있다.
document.querySelector(선택자)
웹 요소 접근할 때 자주 쓰는 CSS 선택자 중 하나로
하나만 콕 집어 선택 가능하고 id 선택자
class 선택자
타입 선택자
하위 선택자
자식 선택자
등에 자주 사용한다.
⇒ querySelector()
함수를 사용하면 지정한 선택자를 사용한 요소 중 첫번째 요소
에 접근할 수 있다.
document.querySelector("#id")
document.querySelector(".class")
document.querySelector("h1")
document.querySelector("#profile img") // 하위 선택자
document.querySelectorAll(선택자)
여러 개의 요소를 가져올 때 사용하며
id 선택자
를 제외한 다른 선택자들은 여러 번 사용할 수 있어서
한꺼번에 여러개의 요소에 접근할 수 있다.
⇒ querySelectorAll()
함수를 사용하면 같은 클래스 이름을 사용하는 요소를 모두 가져와 노드 리스트 형태로 저장하는데(배열과 비슷), 여기에 저장된 요소들은 배열처럼 인덱스를 사용해 접근할 수 있다.
<p class = "user">이름 : 도레미</p>
<p class = "user">주소 : 나도몰라</p>
<p class = "user">연락처 : 010-0000-0000</p>
document.querySelectorAll(".user")
// NodeList(3) [p.user, p.user, p.user]
document.querySelectorAll(".user")[2]
// <p class = "user">연락처 : 010-0000-0000</p>
위 querySelector() 와 querySelectorAll() 나오기 이전에 사용하던 메서드들
클래스와 태그 선택자는 Element 뒤에 s 가 붙어 있다.
메서드 명 | 기능 |
---|---|
getElementById(id명) | id 선택자를 기준으로 접근합니다. |
getElementsByClassName(class명) | class 선택자를 기준으로 접근합니다. |
getElementsByTagName(태그명) | 태그 이름을 기준으로 접근합니다. |
.innerText | .innerHTML | .textContent | |
---|---|---|---|
웹 요소 내용 가져올 경우 | o | x | o |
웹 브라우저 창 표시되지 않은 내용까지 모두 필요 | x | x | o |
요소 안에 있는 태그까지 함께 필요 | x | o | x |
<div id="desc">
<p class="user">이름 : 도레미</p>
<p class="user" style="display:none">주소 : 나도몰라</p>
<p class="user" style="display:none">연락처 : 010-0000-0000</p>
</div>
innerText 프로퍼티는 웹 브라우저 창에 보이는 내용만 가져옵니다.
그래서 display:none 요소의 내용이 없고, 소스에 공백이 여러개 있어도 1개의 공백만 가져옵니다.
document.querySelector("#desc").innerText;
// '이름 : 도레미'
innerHTML 프로퍼티는 #desc 요소 안에 있는 태그와 내용을 (소스 그대로) 함께 가져와서 보여줍니다.
(\n
은 줄이 바뀐 위치를 나타냄)
document.querySelector("#desc").innerHTML;
// '\n <p class="user">이름 : 도레미</p>\n <p class="user" style="display:none">주소 : 나도몰라</p>\n <p class="user" style="display:none">연락처 : 010-0000-0000</p>\n
textContent 프로퍼티는 요소의 내용을 가져오되, 소스에 있는 대로 가져옵니다.
⇒ 감춰진 요소들까지 가져와서 프로그래밍에 사용할 경우 편리하다.
document.querySelector("#desc").textContent;
// '\n 이름 : 도레미\n 주소 : 나도몰라\n 연락처 : 010-0000-0000\n'
.innerText | .innerHTML | .textContent | |
---|---|---|---|
웹 요소 텍스트 내용 바꿀 때 | o | x | o |
웹 요소의 HTML 태그가 포함된 내용 바꿀 때 | x | o | x |
웹요소.innerText = 내용
웹요소.innerHTML = 내용
웹요소.textContent = 내용
이미지 요소에 접근한 후 src
속성값을 바꾸면 이미지를 변경할 수 있는데,
src
속성은 이미지 객체의 src 프로퍼티
로 접근하면 된다.
이미지 요소.src = 이미지파일
제목 클릭했을 때 어느 동작을 하기 위해서는
제목 부분을 가져와서 변수로 저장한 후 함수 연결해서 사용하기
변수.onClick = 함수
title 클릭 했을 때 title 내용을 '프로필'로 바꾸기
title.onClick = function() {
title.innerText = "프로필";
}
// 화살표 함수 사용하기
title.onClick = () => title.innerText = "프로필";
이걸 활용해서 내용과 속성을 수정해보자
const title = document.querySelector("#title"); // 제목 가져오기
const userName = document.querySelector("#desc p"); // 이름 가져오기
const pfImg = document.querySelector("#profile img"); // 이미지 가져오기
title.onClick = () => title.innerText = "프로필";
userName.onClick = () => userName.innerHTML = `이름 : <b>민들레</b>`;
pfImg.onClick = () => pfImg.src = "images/pf2.png";
요소.style.속성명
****
요소.style.color = "수정할 컬러" // 글자색 수정
요소.style.backgroundColor = "수정할 컬러" // 배경색 수정
// 원래는 background-color 인데 두 단어 이상으로 이루어진 속성은
// - 삭제하고 앞의 문자를 대문자로 변경
classList 프로퍼티는 요소에 적용한 클래스 스타일을 모두 모아 놓은 프로퍼티이다.
덕분에 자바스크립트에서 클래스 스타일을 추가 또는 삭제하면서 다양한 효과를 만들 수 있다.
document.querySelector("#desc p").classList
//DOMTokenList(2) ['user', 'clicked', value: 'user clicked\n ']
요소.classList.add(클래스명)
제목 텍스트 클릭했을 때 미리 만들어둔 스타일(.clicked) 를 추가하기
const title = document.querySelector("#title");
title.onClick = () => title.classList.add("clicked");
요소.classList.remove(클래스명)
클래스 리스트에 특정 클래스가 있는지 확인하는 함수
요소.classList.contains(클래스명)
이 함수를 활용해 .clicked 스타일 없으면 .clicked 추가하고
있으면 .clicked 삭제하기
const title = document.querySelector("#title");
title.onClick = () => {
if(!title.classList.contains("clicked")) { // clicked 스타일 없으면
title.classList.add("clicked"); // clicked 스타일 추가
} else { // clicked 스타일 있으면
title.classList.remove("clicked"); // clicked 스타일 삭제
}
}
위 .contains()
의 예제처럼 특정 클래스를 추가하거나 삭제하기를 반복할 경우
.toggle()
을 사용하는게 더 편리하다
⇒ 해당 함수는 버튼을 클릭할 때마다 다크모드로 바뀌거나 원래 상태로 돌릴 때 유용하다.
요소.classList.toggle(클래스명)
제목 텍스트 클릭했을 때 미리 만들어둔 스타일(.clicked) 를 추가하기
const title = document.querySelector("#title");
title.onClick = () => title.classList.toggle("clicked");