5장 DOM의 기초

moono·2023년 1월 31일
0

Do it

목록 보기
2/3

🏁 DOM === DOM 트리

문서 객체 모델(Document Object Model)
웹 문서를 객체로 다루는 시스템으로 HTML, XML 문서의 프로그래밍 인터페이스이다.

문서의 구조화된 표현을 제공 하며
프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공해
그들이 문서구조, 스타일, 내용 등을 변경할 수 있게 돕는다.
⇒ DOM은 HTML을 위한 API 이면서, HTML을 탐색 할 수 있고 구조를 바꿀 수 있다.
⇒ HTML 문서의 계층적 구조와 정보를 표현하며 이를 제어할 수 있는 API, 즉 프로퍼티와 메서드를 제공하는 트리 자료구조이다.

웹 페이지의 객체 지향 표현이며, 자바스크립트와 같은 스크립팅 언어를 이용해 DOM을 수정할 수 있다.
⇒ JavaScript는 브라우저가 읽고 어떤 작업을 할 수 있는 언어 인데,
DOM은 이 작업이 이루어지는 장소 이다.
⇒ 우리가 JS로 하는 것 이라고 생각하는 것은 DOM API 이다.

🤔 DOM을 사용하는 이유는?

  • 자바스크립트를 통해 HTML에서 데이터를 가져오고 싶을 때
  • 웹 페이지 데이터를 동적으로 변경하고 싶을 때
  • 인터렉티브한 웹 애플리케이션을 만들고 싶을 때

➰ 노드 Node

HTML 요소(엘리먼트) 는 HTML 문서를 구성하는 개별적인 요소를 의미하는데,
이 요소들이 렌더링 엔진에 의해 파싱되어 DOM을 구성하는 요소 노드 객체 로 변환된다.
⇒ HTML요소의 어트리뷰트는 어트리뷰트 노드로, 텍스트콘텐츠는 텍스트 노드로 변환
body 안에 h1 요소의 내용h1의 자식 노드 가 된다.

HTML요소 간 중첩 관계(포함 관계)에 의해 계층적인 부자 관계가 형성되는데,
이러한 부자 관계를 반영해 HTML 요소를 객체화한 모든 노드 객체들을 트리 자료 구조로 구성한다.

📌 중요한 노드 타입 4가지

노드 객체는 종류가 있고 상속 구조를 갖는데, 총 12개의 종류가 있다.

  • 문서 노드 (Document node) : 문서 전체를 나타내는 노드
    DOM 트리의 최상위에 존재하는 루트 노드로서 document 객체를 가르키고, window.document 또는 document로 참조할 수 있다.
    ⇒ DOM 트리의 노드들에 접근하기 위한 진입점 역할을 담당한다.
    ⇒ 요소, 어트리뷰트, 텍스트 노드에 접근하려면 문서 노드를 통해야 한다.

  • 요소 노드 (Element node) : 속성 노드를 가질 수 있는 유일한 노드
    HTML 요소를 가리키는 객체로
    HTML 요소 간의 중첩에 의해 부자관계를 가지며, 이 부자관계를 통해 정보를 구조화한다.
    ⇒ 문서의 구조를 표현한다고 할 수 있다.

  • 속성 노드 (Attribute node) : 요소 노드에 관한 정보를 가지고 있다.
    HTML 요소의 어트리뷰트를 가리키는 객체로 어트리뷰트가 지정된 HTML 요소의 요소 노드와 연결되어 있다.
    ⇒ 어트리뷰트 노드는 부모 노드와 연결되어 있지 않고 요소 노드에만 연결되어 있기 때문에, 요소 노드의 형제 노드가 아니다.
    ⇒ 어트리뷰트를 참조하거나 변경하려면 먼저 요소 노드에 접근해야 한다.

  • 텍스트 노드 (Text node)
    HTML 요소의 텍스트를 가리키는 객체로, 요소 노드가 문서의 구조를 표현한다면 텍스트 노드는 문서의 정보를 표현한다고 할 수 있다.
    ⇒ 요소 노드의 자식 노드이지만 자식노드를 가질 수 없는 리프 노드이다.
    ⇒ DOM 트리의 최종단인데, 텍스트 노드에 접근하려면 부모 노드인 요소 노드에 접근해야 한다.


✔️ DOM 트리

➰ 트리 자료구조

노드들의 계층 구조로 이루어진다.
부모 노드와 자식 노드로 구성되어 노드 간의 계층적 구조를 표현하는 비선형 자료구조를 말한다.

  • 노드 : DOM 트리에서 가지가 갈라져 나가는 부분
  • 루트 노드 : DOM 트리의 최상위 노드(부모 노드가 없고, 0개 이상의 자식 노드를 가짐)
  • 리프 노드 : 자식 노드가 없는 노드
  • 형제 노드 : 같은 부모 노드를 가진 노드들
📌 비선형 자료구조란? 하나의 자료 뒤에 여러 개의 자료가 존재할 수 있는 자료구조(💔 반대 개념 선형 자료구조(배열, 큐, 스택 등))

🏁 웹 요소에 접근하기

웹 문서에 있는 이미지나 테스트, 표 등 특정 요소를 찾아가는 것을 웹 요소에 접근한다 라고 하는데, 이렇게 접근하면 해당 요소의 내용이나 값을 가져오거나 수정할 수 있다.

➰ querySelector()

document.querySelector(선택자)

웹 요소 접근할 때 자주 쓰는 CSS 선택자 중 하나로
하나만 콕 집어 선택 가능하고 id 선택자 class 선택자 타입 선택자 하위 선택자 자식 선택자 등에 자주 사용한다.
querySelector() 함수를 사용하면 지정한 선택자를 사용한 요소 중 첫번째 요소 에 접근할 수 있다.

document.querySelector("#id")
document.querySelector(".class")
document.querySelector("h1") 
document.querySelector("#profile img") // 하위 선택자

➰ querySelectorAll()

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>

➰ getElement 메서드

위 querySelector() 와 querySelectorAll() 나오기 이전에 사용하던 메서드들
클래스와 태그 선택자는 Element 뒤에 s 가 붙어 있다.

메서드 명기능
getElementById(id명)id 선택자를 기준으로 접근합니다.
getElementsByClassName(class명)class 선택자를 기준으로 접근합니다.
getElementsByTagName(태그명)태그 이름을 기준으로 접근합니다.


🏁 웹 요소 내용 가져오기

.innerText.innerHTML.textContent
웹 요소 내용 가져올 경우oxo
웹 브라우저 창 표시되지 않은 내용까지 모두 필요xxo
요소 안에 있는 태그까지 함께 필요xox

🏷 예시로 확인하기!

<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

innerText 프로퍼티는 웹 브라우저 창에 보이는 내용만 가져옵니다.
그래서 display:none 요소의 내용이 없고, 소스에 공백이 여러개 있어도 1개의 공백만 가져옵니다.

document.querySelector("#desc").innerText;
// '이름 : 도레미'

➰ .innerHTML

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

textContent 프로퍼티는 요소의 내용을 가져오되, 소스에 있는 대로 가져옵니다.
⇒ 감춰진 요소들까지 가져와서 프로그래밍에 사용할 경우 편리하다.

document.querySelector("#desc").textContent;
// '\n  이름 : 도레미\n  주소 : 나도몰라\n  연락처 : 010-0000-0000\n'


🏁 웹 요소 내용 수정하기

.innerText.innerHTML.textContent
웹 요소 텍스트 내용 바꿀 때oxo
웹 요소의 HTML 태그가 포함된 내용 바꿀 때xox
웹요소.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";


🏁 스타일 수정하기

✔️ CSS 속성에 접근하고 수정하기

요소.style.속성명
****
요소.style.color = "수정할 컬러" // 글자색 수정
요소.style.backgroundColor = "수정할 컬러" // 배경색 수정
// 원래는 background-color 인데 두 단어 이상으로 이루어진 속성은
// - 삭제하고 앞의 문자를 대문자로 변경

✔️ classList 프로퍼티

classList 프로퍼티는 요소에 적용한 클래스 스타일을 모두 모아 놓은 프로퍼티이다.
덕분에 자바스크립트에서 클래스 스타일을 추가 또는 삭제하면서 다양한 효과를 만들 수 있다.

document.querySelector("#desc p").classList
//DOMTokenList(2) ['user', 'clicked', value: 'user clicked\n      ']

➰ .add() : 클래스 스타일 추가하기

요소.classList.add(클래스명)

제목 텍스트 클릭했을 때 미리 만들어둔 스타일(.clicked) 를 추가하기

const title = document.querySelector("#title");

title.onClick = () => title.classList.add("clicked");

➰ .remove() : 클래스 스타일 삭제하기

요소.classList.remove(클래스명)

➰ .contains() : 특정 클래스 스타일 있는 요소 찾기

클래스 리스트에 특정 클래스가 있는지 확인하는 함수

요소.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 스타일 삭제
  }
}

➰ .toggle() : 클래스 스타일 토글하기

.contains() 의 예제처럼 특정 클래스를 추가하거나 삭제하기를 반복할 경우
.toggle() 을 사용하는게 더 편리하다
⇒ 해당 함수는 버튼을 클릭할 때마다 다크모드로 바뀌거나 원래 상태로 돌릴 때 유용하다.

요소.classList.toggle(클래스명)

제목 텍스트 클릭했을 때 미리 만들어둔 스타일(.clicked) 를 추가하기

const title = document.querySelector("#title");

title.onClick = () => title.classList.toggle("clicked");


📌 Reference

노드

0개의 댓글