IWished
article thumbnail

DOM

DOM이란, 자바스크립트 같은 프로그래밍 언어로 웹 문서에 접근하고 제어할 수 있도록 웹 문서를 체계적으로 정리하는 방법을 말한다.

DOM에서는 웹 문서를 하나의 객체로 정의하고, 웹 문서 전체는 document 객체로, 웹 문서에 삽입된 이미지는 image 객체로 나타내는 등 웹 문서와 그 안의 요소들을 객체로 인식하고 조절한다.

이를 문서 객체 모델 이라고도 한다.

 

DOM 트리

DOM에서 웹 문서를 구조화하려면 먼저 웹 문서 구조를 부모 요소와 자식 요소로 구분해서 포함 관계를 나타내야 한다.

이를 구분해서 표시하다 보면 마치 나무처럼 모양이 나타나 이것을 DOM 트리 라고 부른다.

DOM 트리에서 가지가 갈라져 나가는 부분은 노드(node), DOM 트리의 시작 부분인 html 노드 같은 경우 나무의 뿌리에 해당하는 루트 노드(root node) 라고 한다.

 

웹 요소에 접근하기

자바스크립트에서 웹 문서에 있는 이미지나 텍스트, 표 등 특정 요소를 찾아가는 것을 '웹 요소에 접근한다' 라고 한다.

1. 내용이나 값 가져오기

선택자를 사용해 웹 요소에 접근할 때는 querySelector() 함수나 querySelectorAll() 함수를 사용한다.

이 때 객체에 포함된 함수를 '메서드(Method)' 라고도 한다.

1.1 querySelector()

querySelector() 함수를 사용하면 지정한 선택자를 사용한 요소 중 첫 번째 요소에 접근할 수 있다.

document.querySelector(선택자)

1.2 querySelectorAll()

querySelectorAll() 함수는 여러 개의 요소를 가져올 때 사용한다.

document.querySelectorAll(선택자)

2. 내용을 가져오고 수정하기

자바스크립트를 이용해 웹 요소에 접근한 후 내용을 가져오거나 수정할 수 있다.

이때 innerText 프로퍼티innerHTML 프로퍼티, textContent 프로퍼티를 사용한다.

2.1 innerText

innerText 프로퍼티는 웹 브라우저 창에 보이는 내용만 가져온다.

"display:none"을 사용해서 화면에 감춘 요소의 내용도 가져오지 않고, 소스에 공백이 여러 개 입력되어 있어도 웹 브라우저 창에 보이는 대로 공백 1칸만 가져온다.

document.querySelector("#desc").innetText

2.2 innerHTML

innerHTML 프로퍼티는 웹 요소 안에 있는 태그와 내용을 함께 가져와서 보여준다.

즉, 웹 브라우저 창에 어떻게 보이는지와는 상관없이 소스에 있는대로 가져온다.

document.querySelector("#desc").innerHTML

2.3 textContent

testContent 프로퍼티는 요소의 내용을 가져오되, 소스에 있는 대로 가져온다.

"display:none"으로 감춰둔 텍스트 내용도 보여주고, 여러 칸의 공백도 그대로 표시한다.

document.querySelector("#desc").textContent

DOM 요소 내용과 속성 수정하기

const title = document.querySelector("#title");   // 제목 부분 가져오기
const userName = document.querySelector("#desc p");   // 이름 부분 가져오기
const pfImage = document.querySelctor("#profile img");   // 프로필 이미지 가져오기

title.onclick = () => title.innetText = "프로필";
userName.onclick = () => userName.innerHTML = `이름 : <b>민들레</b>`;
pfImage.onclick = () => pfImage.src = "images/pf2.png";

스타일 수정하기

자바스크립트를 이용해 스타일 속성의 값을 가져오거나 원하는 값으로 수정할 수도 있다.

1. CSS 속성에 접근하고 수정하기

자바스크립트를 사용해 CSS 속성에 접근하려면 예약어 .styleCSS 속성을 사용해야 한다.

요소.style.속성명

2. classList

classList는 DOM에서 자주 사용하는 프로퍼티이다.

2.1 classList - Methods

  • add(String)
    • 지정한 클래스 값을 추가한다.
    • 만약 추가하려는 클래스가 이미 존재한다면 무시
  • remove(String)
    • 지정한 클래스 값을 제거한다.
  • contains(String)
    • 지정한 클래스 값이 존재하는지 확인한다.
    • true, false 값을 반환
  • replace(old, new)
    • old class를 new class로 대체한다.
  • item(Number)
    • 인덱스 값을 활용하여 클래스 값을 반환한다.
  • toggle
    • toggle은 클래스의 유무를 체크해서 없으면 add, 있으면 remove를 자동으로 시켜준다.

DOM Event

자바스크립트에서 이벤트는 다양한 상황에서 발생한다.

마우스 클릭, 키보드 프레스 이벤트 뿐 아니라, 페이지 로딩, 스크롤, 요소 선택 등 다양한 상황에서 이벤트가 발생하며,

이러한 이벤트를 다루어 사용자와 인터랙션하는 웹을 만드는 것이 웹브라우저에서 동작하는 자바스크립트의 중요한 역할이다.

이벤트 발생 시점

이벤트는 다양한 상황에서 발생한다.

 

UI 이벤트

  • load - 페이지와 기타요소들의 로딩이 완료되었을 때
  • unload - 웹 페이지가 언로드될 때(주로 새로운 페이지를 요청한 경우)
  • error - 자바스크립트 오류를 만났거나 요청한 자원이 존재하지 않을때
  • resize - 브라우저 창의 크기를 조정했을 때
  • scroll - 사용자가 페이지를 스크롤할 때

키보드 이벤트

  • keydown - 사용자가 키를 처음 눌렀을 때
  • keyup - 사용자가 키를 땔 때
  • keypress - 사용자가 눌렀던 키의 문자가 입력되었을 때

마우스 이벤트

  • click - 사용자가 페이지 위에서 마우스를 클릭했을 때
  • dblclick - 더블클릭
  • mousedown - 마우스 버튼 누르고 있을때
  • mouseup - 마우스 버튼을 뗄 때
  • mousemove - 마우스를 움직일 때
  • mouseenter - 요소 위로 마우스를 움직였을 때
  • mouseleave - 요소 밖으로 마우스를 움직였을 때
  • dragstart - 드래그 시작
  • drag - 드래그
  • dragend - 드래그 종료
  • mouseover - 마우스를 요소 위로 올렸을 때. CSS의 :hover 클래스를 이용할 것.
  • mouseout - 마우스가 요소 밖으로 벗어났을 때. CSS의 :hover 클래스를 이용할 것.

터치 이벤트

  • touchstart - 화면을 건드렸을 때
  • touchend - 화면에서 손을 떼었을 때
  • touchmove - 화면에서 터치로 이동 중일 떄

포커스 이벤트

  • focus / focusin - 요소가 포커스를 얻었을 때
  • blur / focusout - 요소가 포커스를 잃었을 때

폼 이벤트

  • input - input, textarea 값이 변경되었을 때
  • change - 선택상자, 체크박스, 라디오 버튼의 상태가 변경되었을 때
  • submit - 사용자가 폼을 제출할 때
  • reset - 리셋버튼을 클릭할 때
  • cut - 폼필드의 콘텐츠를 잘라낼 때
  • copy - 폼필드의 콘텐츠를 복사할 때
  • paste - 폼필드에 콘텐츠를 붙여넣을 때
  • select - 폼필드에서 텍스트를 선택할 때

Transiton 이벤트

  • transitionend - CSS transition이 완료되면 발생

Media 이벤트

  • abort - 미디어 로드 / 재생이 중단될 때.
  • canplay - 미디어를 재생할 수있는 충분한 데이터가 있을 때
  • canplaythrough - 버퍼링 없이 전체 미디어를 재생할 수 있을 때
  • durationchange - 미디어의 지속 시간이 변경되었을 때
  • emptied - 미디어가 비어있을 때. load() 메서드가 호출되어 다시 로드되기 전.
  • ended - 재생이 완료되면 발생
  • error - 오류가 발생하면 전송된다.
  • loadeddata - 미디어의 현재 프레임이 로드될 때
  • loadedmetadata - 미디어의 메타 데이터 로드가 완료되었을 때
  • loadstart - 미디어 로드가 시작될 때
  • pause - 재생이 일시 정지될 때
  • play - 이전 일시 정지 이벤트 이후에 재생이 재개 될 때
  • playing - 미디어가 재생되기 시작할 때
  • progress - 미디어 다운로드 진행 상황을 알리기 위해 주기적으로 전송된다. 미디어 요소의 buffered 속성에서 사용할 수 있다.
  • ratechange - 재생 속도가 변경될 때
  • seeked - 탐색이 완료될 때
  • seeking - 탐색이 시작될 때
  • stalled - 미디어 데이터를 가져오려고 하는데 데이터가 갑자기 나타나지 않을 때 발생
  • suspend - 미디어의 로딩이 일시 중지되면 발생
  • timeupdate - 요소의 currentTime 속성이 나타내는 시간이 변경될 때
  • volumechange - 오디오 볼륨이 변경되면 전송
  • waiting - 요청한 작업이 지연되어 다른 작업이 완료 되는것을 기다릴 때 (버퍼링 시)

HTML5 이벤트

  • DOMContentLoaded - DOM 트리가 생성될 때
  • hashchange - URL의 해시가 변경될 때 발생한다. 해시는 페이지 내의 특정 영역에 연결하기 위해서 사용하며, AJAX를 이용하여 컨텐츠를 로드하는 경우에도 사용힌다.
  • beforeunload - 페이지가 언로드되기 전에 발생한다. 사용자가 폼 데이터를 변경한 상태에서 저장하지 않고 이동하려는 경우에 이를 알려주는 용도 등으로 사용한다.

DOM Node

DOM은 Node의 계층 구조로 이루어져 있다. 각 노드는 부모와 children을 가질 수 있다.

<!DOCTYPE html>
<html>
  <head>
    <title>My Page</title>
  </head>
  <body>
    <!-- Page Body -->
    <h2>My Page</h2>
    <p id="content">Thank you for visiting my web page!</p>
  </body>
</html>

위의 HTMl은 아래에 있는 노드들의 계층으로 구성되어있다.

HTML에 있는 tag (<html>, <p>와 같은...)들은 node를 표현하게 된다. 여기서 그저 text이더라도 node가 된다는 점이다. 노드트리를 보면, <p> 자식 노드로 text node가 있는 것을 확인할 수 있다.

 

Node Type

Node.ELEMENT_NODE
Node.ATTRIBUTE_NODE
Node.TEXT_NODE
Node.CDATA_SECTION_NODE
Node.PROCESSING_INSTRUCTION_NODE
Node.COMMENT_NODE
Node.DOCUMENT_NODE
Node.DOCUMENT_TYPE_NODE
Node.DOCUMENT_FRAGMENT_NODE
Node.NOTATION_NODE

Node.ELEMENT_NODE 외에도, 주석의 타입인 COMMENT_NODE와 전체 document tree를 표현하는
Node.DOCUMENT_NODE도 있다.

DOM Element

Element는 node의 특정 타입 즉, Node.ELEMENT_NODE인 것이다.

element는 HTML에서 태그로 적은 노드들을 지칭한다. 예를 들어, <html>, <div>, <title> 과 같은 태그로 나타낸 것들은 전부 element인 것이다. 주석이나 text node와 같은 것들은 HTML 태그로 표현된 것이 아니므로 element가 아니다.

JS DOM에서Node는 node의 constructor이고, HTMLElement는 element의 constructor이다.

paragraph는 node이자 동시에 element이다.

const paragraph = document.querySelector('p');

paragraph instanceof Node;        // => true
paragraph instanceof HTMLElement; // => true

DOM 프로퍼티

node에만 있는 DOM 프로퍼티와 element에만 있는 DOM 프로퍼티를 구분할 줄 알아야 한다.

다음 Node의 프로퍼티들은 node나 NodeList라고 한다.

node.parentNode; // Node or null

node.firstChild; // Node or null
node.lastChild;  // Node or null

node.childNodes; // NodeList

다음 Node의 프로퍼티들은 element나 element의 집합(HTMLCollection)이다.

node.parentElement; // HTMLElement or null

node.children;      // HTMLCollection

여기서 주목할 것은 Node의 children을 가져오는 프로퍼티라는 점에서는 같지만, NodeList 형태로 가져오는 node.childNodes와 HTMLCollection 형태로 가져오는 node.children이 있다는 것이다.