╱╱╭╮╱╱╱╱╱╱╭━━━╮╱╱╱╭╮╱╭╮╱╱╱╱╱╱ ╱╱┃┃╱╱╱╱╱╱┃╭━╮┃╱╱╱┃┃╱┃┃╱╱╱╱╱╱ ╱╱┃┣━━┳━━╮┃┃╱┃┣━╮╱┃╰━╯┣━━┳━╮╱ ╭╮┃┃╭╮┃┃━┫┃╰━╯┃╭╮╮┃╭━╮┃╭╮┃╭╮╮ ┃╰╯┃╭╮┃┃━┫┃╭━╮┃┃┃┃┃┃╱┃┃╭╮┃┃┃┃ ╰━━┻╯╰┻━━╯╰╯╱╰┻╯╰╯╰╯╱╰┻╯╰┻╯╰╯

Javascript/Javascript 기초

[Javascript] DOM, HTML DOM API, document

재안안 2024. 5. 4. 21:27

개요

[1] DOM이란?

[2] DOM 트리

[3] DOM 요소 접근법

[4] DOM 노드란?

[5] DOM 이벤트

[6] DOM 요소 제어

[7] DOM 트리 제어

[8] HTML DOM이란?

[9] document

[10] reference

 

 

[1] DOM이란?

Document Object Model

connecting web pages to scripts (javascript) by representing the structure of a document as logical tree

document 객체는 DOM에 접근하기 위한 진입점이다.

 

 

document를 통한 접근

<html> = document.documentElement

<body> = document.body

<head> = document.head

 

브라우저가 <body>를 읽지 못했을 땐, document.body = null

서버 사이드 스크립트에서도 DOM을 사용한다.

 

[2] DOM 트리

DOM 트리의 노드는 웹 문서의 HTML 요소에 국한되지 않는다.

  - Element 노드

  - Text 노드

  - Attribute 노드

  - Comment 노드

 

줄바꿈도 빈 텍스트 노드로 인식한다.

자식 노드(child node, children)이란, 바로 아래의 직계 자식 노드를 뜻한다.

후손 노드 (descendants)란, 트리 구조상 아래의 모든 노드를 뜻한다.

형제 노드 (sibling)란, 같은 부모는 가진 노드를 뜻한다.

 

firstChild, lastChild, nextSibling, previousSibling, parentNode

 

Array.from(document.body.childNodes).filter(( ) => { }); // Array-like

 

<html>은 parentNode가 null

 

 

[3] DOM 요소 접근법

getElementById : ( 'id' ) => Element

getElemeentsByClassName : ( 'class' ) => HTMLCollection

getElementsByTagName : ( 'tag' ) => HTMLCollection

querySelector : ( 'CSS selector' ) => Element

querySelectorAll : ( CSS selector ) => NodeList

 

element 계열 함수들은 DOM 트리에서 요소 노드까지만 접근 가능

element 계열 함수의 반환 값은 문서에 변경이 있을 때마다 자동갱신 되어 최신 상태를 유지한다. (참조형?)

element 계열 함수는 document를 통해서만 사용 가능

 

<div>첫 번째 div</div>

<script>
  let divs = document.getElementsByTagName('div');
  alert(divs.length); // 1
</script>

<div>두 번째 div</div>

<script>
  alert(divs.length); // 2
</script>

 

 

query 계열 함수들은 요소 노드 내부의 텍스트 노드 및 속성 노드까지 접근 가능

query 계열 함수의 반환 값은 정적이다. (자동갱신x)

 

 

[4] DOM 노드란?

브라우저는 HTML을 파싱해 DOM 객체를 만들 때 HTML 표준 속성을 인식하고,

이 표준 속성을 사용해 DOM 프로퍼티를 만든다.

 

DOM 노드 상속 구조

EventTarget <- Node <- Element <- HTMLElement

 

EventTarget 

자바스크립트의 이벤트 동작에 기반이 되는 추상 클래스

 

Node

DOM 트리에서 주변 노드 탐색 기능을 제공하는 추상 클래스

 

Element

getElementById와 querySelector와 같이 특정 노드 탐색 기능을 제공하는 클래스

 

Node Property

nodeName, innerHTML, outerHTML, textContent, hidden, id

 

innerHTML

DOM.innerHTML += "<div>안녕하세요<img src='smile.gif'/> !</div>" ;를 수행 시

기존 내용에 추가되는게 아니라

기존 내용을 삭제후 내용을 다시 쓰기 때문에 리소스 전부 다시 로딩됨.

 

normalize : () => None

Before normalization:
#text: Part 1
#text: Part 2

After normalization:
#text: Part 1 Part 2

 

HTML 노드의 속성을 가져오거나 수정

getAttribute : ( 'key' ) => 'value'

setAttribute : ( 'key', 'value' ) => undefined

removeAttribute : ( 'key' ) => undefined

hasAttribute : (  'key' ) => boolean

 

HTMLElement Property

attributes : Attr 컬렉션 (iterable)

 

몇몇 경우를 제외하고 프로퍼티와 속성은 동기화된다. (value)

DOM의 property가 변하면 HTML attribute이 갱신된다.

 

비표준 속성

<body data-about="Elephants">

<script>

  alert(document.body.dataset.about); // Elephants

</script>

 

 

[5] DOM 이벤트 처리

addEventListener : (string, listner, boolean) => undefined

매개변수 1. 이벤트 유형

매개변수 2. 이벤트를 listen할 객체 또는 콜백 함수

매개변수 3. true면 캡처링 false면 버블링

 

캡처링 : DOM 트리에서 이벤트 전달 방식이 부모 -> 자식

버블링 : DOM 트리에서 이벤트 전달 방식이 자식 -> 부모

 

이벤트는 캡처링, 버블링 순으로 전달되며 이 점을 활용하면 중복되는 이벤트 등록을 막아 메모리를 아낄 수 있다.

 

addEventListener : (string, listner , object) => undefined

매개변수 1. 이벤트 유형

매개변수 2. 이벤트를 listen할 객체 또는 콜백 함수

매개변수 3. { capture, once, passive, signal }

  - capture : 위와 같

  - once : true면 한번 실행 후 remove

  - passive : listener가 preventDefault를 호출하지 않을 것임을 명시

  - signal : AbortSignal 객체를 받는데 해당 객체의 abort가 호출되면 listener는 제거됨

 

이벤트 하나에 하나 이상의 핸들러 적용가능

화살표 함수가 아닌 함수에서 this는 e.currentTarget

HTML 요소 아니더라도 EventTarget 상속 받으면 dispatch - listen 적용 가능

dispatchEvent (fire event)와 addEventListener (invoke handlers synchronously)는 나중에 정리

 

 

[6] DOM 요소 제어

createElement : ( 'tag' ) => HTMLElement | HTMLUnknownElement

createTextNode : ( 'text' ) => Text

createAttribute : ( 'name' ) => Attr

setAttributeNode : () => Attr | null

cloneNode : ( boolean ) => Node

  - 매개변수 1. true면 자식 노드까지 아니면 해당 노드만 값 복사

 

 

[7] DOM 트리 제어

node.append(노드나 문자열) – 노드나 문자열을 node 끝에 삽입

node.prepend(노드나 문자열) – 노드나 문자열을 node 맨 앞에 삽입

node.before(노드나 문자열) –- 노드나 문자열을 node 이전에 삽입

node.after(노드나 문자열) –- 노드나 문자열을 node 다음에 삽입

node.replaceWith(노드나 문자열) –- node를 새로운 노드나 문자열로 대체

 

insertAdjacentHTML : ( str, str ) => undefined

매개변수 1. where

  - 'beforebegin'  elem 바로 앞에 html을 삽입

  - 'afterbegin'  elem의 첫 번째 자식 요소 바로 앞에 html을 삽입

  - 'beforeend'  elem의 마지막 자식 요소 바로 다음에 html을 삽입

  - 'afterend'  elem 바로 다음에 html을 삽입

 

매개변수 2. HTML 문자열

  - 이스케이프 처리되지 않그 그대로 삽입

 

모든 노드 삽입 메서드는 기존에 있던 노드를 삭제하고 새로운 곳으로 노드를 옮긴다.

 

appendChild : () => Node | DocumentFragment

removeChild : ( Node ) => Node

hasChildNodes : () => boolean

insertBefore : ( Node, Node ) => Node | DocumentFragment

 

DOM에서 children 속성에 접근하면 HTMLCollection이 있다.

parentNode 속성으로 부모 노드에 접근가능

removeChild 호출 후 반환값을 무시하고 해당 노드가 다른 곳에서도 더이상 참조되지 않는다면 메모리에서도 지워지게된다.

 

document.write

 

use of document.write is strongly discouraged

 

document.write() writes to the document stream called document.write() on a closed (loaded) document automatically calls document.open(), which will clear the document

 

페이지를 불러오는 도중에만 동작한다.

페이지 로드후 document.write를 호출하면 기존에 있던 문서 내용이 사라진다.

<p>일 초 후, 이 페이지의 내용은 전부 교체됩니다.</p>
<script>
  // 일초 후 document.write 호출
  // 페이지 로드가 끝난 후이므로 기존 내용이 사라집니다.
  setTimeout(() => document.write('<b>...사라졌습니다.</b>'), 1000);
</script>

 

브라우저는 HTML을 ‘읽는(파싱하는)’ 도중에 document.write(HTML)를 만나면 텍스트 형식의 HTML을 마치 원래 페이지에 있었던 것 마냥 해석한다.

 

중간에 DOM 조작을 하지 않기 때문에 속도가 아주 빨라진다.

DOM 구조가 완성되기 전에 페이지에 내용이 삽입되기 때문

 

엄청나게 많은 글자를 HTML에 동적으로 추가해야 하는데 아직 페이지를 불러오는 중이고, 속도가 중요한 상황이라면 document.write가 유용할 수 있다.

 

 

[8] HTML DOM이란?

interfaces defining the functionality of each of the HTML elements

HTML DOM API와 HTML elements는 거의 1대1로 매핑된다

 

HTML element 상속 구조

EventTarget <- Node <- Element <- HTMLElement

 

HTMLElement provides only the functionality common to all HTML elements such as element's ID, coordinates, information about scroll position, and  the HTML making up the element.

 

HTML DOM API는 그냥 HTML 태그를 (js로) 더 깊이있게 제어하는 용도이다.

 

<form>과 <input>

- FormData

- ValidityState

 

<canvas>

- CanvasRenderingContext2D

- ImageBitmapRenderingContext

- OffscreenCanvasRenderingContext2D

- Path2D

- TextMatrix

 

 

[9] document

 

classList (iterable)

  - elem.classList.add/remove("class")

  - elem.classList.toggle("class")

  - elem.classList.contains("class")

 

cssText

<div id="div">버튼</div>

<script>
  // cssText를 사용하면 'important' 같은 규칙도 설정할 수 있습니다.
  div.style.cssText=`color: red !important;
    background-color: yellow;
    width: 100px;
    text-align: center;
  `;

  alert(div.style.cssText);
</script>

 

 

exitFullScreen : () => Promise

elementsFromPoint : ( int, int ) => Array

hasFocus : () => boolean

hasStorageAccess : () => Promise

requestStorageAccess : () => Promise

 

 

추가적으로 흥미로운 API들

Web Workers API : DOM과 관련 없는 작업을 백그라운드 스레드에서 시킬 수 있음 

WebSockets API : persistent browser-server connections

 

 

[10] reference

 

https://developer.mozilla.org/ko/

 

MDN Web Docs

The MDN Web Docs site provides information about Open Web technologies including HTML, CSS, and APIs for both Web sites and progressive web apps.

developer.mozilla.org

 

https://ko.javascript.info/ui

 

브라우저: 문서, 이벤트, 인터페이스

 

ko.javascript.info