쑤쑤_CS 기록장
31. 문서 객체 모델(Document Object Model) 본문
#1. DOM ( Document Object Model )
DOM
- 브라우저의 렌더링 엔진
: 웹 문서를 로드 -> 파싱하여 웹 문서를 브라우저가 이해할 수 있는 구조로 구성 ->메모리에 적재 -
모든 요소와 어트리뷰트, 텍스트를 각각의 객체로 만들고 이를 부자 관계로 표현할 수 있는 트리구조로 구성한 것
DOM API (Application Programming Interface)
- 웹 문서의 동적 변경을 위해 일반적으로 프로퍼티와 메소드를 갖는 자바스크립트 객체로 제공
-
정적인 웹페이지에 접근하여 동적으로 웹페이지를 변경하기 위한 방법 : DOM 변경
-
DOM에 접근하고 변경하는 프로퍼티와 메소드의 집합 : DOM API
< DOM의 기능(2) >
- HTML 문서에 대한 모델 구성
: 브라우저는 HTML 문서를 로드한 후 해당 문서에 대한 모델을 메모리에 생성한다. 이때 모델은 객체의 트리로 구성되는데 이것을 DOM tree라 한다.
- HTML 문서 내의 각 요소에 접근 / 수정
: DOM은 모델 내의 각 객체에 접근하고 수정할 수 있는 프로퍼티와 메소드를 제공한다. DOM이 수정되면 브라우저를 통해 사용자가 보게 될 내용 또한 변경된다.
#2. DOM tree
: 브라우저가 HTML 문서를 로드한 후 파싱하여 생성하는 모델. 객체의 트리로 구조화되어있다.
<!DOCTYPE html>
<html>
<head>
<style>
.red { color: #ff0000; }
.blue { color: #0000ff; }
</style>
</head>
<body>
<div>
<h1>Cities</h1>
<ul>
<li id="one" class="red">Seoul</li>
<li id="two" class="red">London</li>
<li id="three" class="red">Newyork</li>
<li id="four">Tokyo</li>
</ul>
</div>
</body>
</html>
-
모든 요소, 어트리뷰트, 텍스트는 하나의 객체. Document 객체의 자식
-
진입점(Entry point)은 document 객체
-
최종점은 요소의 텍스트를 나타내는 객체
< DOM tree의 노드(4) >
- 문서 노드(Document Node)
: 트리의 최상위에 존재하며 각각 요소, 어트리뷰트, 텍스트 노드에 접근하려면 문서 노드를 통해야 한다. 즉, DOM tree에 접근하기 위한 시작점(entry point)이다. - 요소 노드(Element Node)
: 요소 노드는 HTML 요소를 표현한다. HTML 요소는 중첩에 의해 부자 관계를 가지며 이 부자 관계를 통해 정보를 구조화한다. 따라서 요소 노드는 문서의 구조를 서술한다고 말 할 수 있다. 어트리뷰트, 텍스트 노드에 접근하려면 먼저 요소 노드를 찾아 접근해야 한다. 모든 요소 노드는 요소별 특성을 표현하기 위해 HTMLElement 객체를 상속한 객체로 구성된다. - 어트리뷰트 노드(Attribute Node)
: 어트리뷰트 노드는 HTML 요소의 어트리뷰트를 표현한다. 어트리뷰트 노드는 해당 어트리뷰트가 지정된 요소의 자식이 아니라 해당 요소의 일부로 표현된다. 따라서 해당 요소 노드를 찾아 접근하면 어트리뷰트를 참조, 수정할 수 있다. - 텍스트 노드(Text Node)
: 텍스트 노드는 HTML 요소의 텍스트를 표현한다. 텍스트 노드는 요소 노드의 자식이며 자신의 자식 노드를 가질 수 없다. 즉, 텍스트 노드는 DOM tree의 최종단이다.
DOM tree의 객체 구성
#3. DOM Query / Traversing (요소에의 접근)
3.1 하나의 요소 노드 선택 (DOM Query)
- document.getElementById(id)
-
id 어트리뷰트 값으로 요소 노드를 한 개 선택
-
복수개가 선택될 경우, 첫번째 요소만 반환
-
Return : HTMLElement를 상속받은 객체
-
- document.querySelector(cssSelector)
-
CSS 셀렉터를 사용하여 요소 노드를 한 개 선택
-
복수개가 선택될 경우, 첫번째 요소만 반환
-
Return : HTMLElement를 상속받은 객체
-
#3.2 여러 개의 요소 노드 선택 (DOM Query)
-
document.getElementsByClassName(class)
- class 어트리뷰트 값으로 요소 노드를 모두 선택
- 공백으로 구분하여 여러 개의 class 지정 가능
- Return : HTMLCollection(live)
-
document.getElementsByTagName(tagName)
- 태그명으로 요소 노드를 모두 선택
- Return : HTMLCollection(live)
-
document.querySelectorAll(selector)
- 지정된 CSS 선택자를 사용하여 요소 노드를 모두 선택
- Return : NodeList (non-live)
#3.3 DOM Traversing (탐색)
- parentNode
- 부모 노드를 탐색
- Return : HTMLElement를 상속받은 객체
- firstChild, lastChild
- 자식 노드를 탐색
- Return : HTMLElement를 상속받은 객체
- hasChildNodes()
- 자식 노드가 있는지 확인하고 Boolean 값을 반환
- Return : Boolean 값
- childNodes
- 자식 노드의 컬렉션을 반환
- 텍스트 요소를 포함한 모든 자식 요소를 반환
- Return : NodeList (non-live)
- children
- 자식 노드의 컬렉션을 반환
- 자식 요소 중에서 Element type 요소만을 반환
- Return : HTMLCollection(live)
- previousSibling, nextSibling
- 형제 노드를 탐색
- text node를 포함한 모든 형제 노드를 탐색
- Return : HTMLElement를 상속받은 객체
- previousElementSibling, nextElementSibling
- 형제 노드를 탐색
- 형제 노드 중에서 Element type 요소만을 탐색
- Return : HTMLElement를 상속받은 객체
4. DOM Manipulation (조작)
#4.1 텍스트 노드의 접근/수정
요소의 텍스트는 텍스트 노드에 저장되어 있다.
< 텍스트 노드에 접근하기위한 순서 >
- 해당 텍스트 노드의 부모 노드를 선택한다. 텍스트 노드는 요소 노드의 자식이다.
- firstChild 프로퍼티를 사용하여 텍스트 노드를 탐색한다.
- 텍스트 노드의 유일한 프로퍼티(nodeValue)를 이용하여 텍스트를 취득한다.
- nodeValue를 이용하여 텍스트를 수정한다.
- nodeValue
- 노드의 값을 반환
- Return : 텍스트 노드 → 문자열 / 요소 노드 → null
- nodeName
- nodeType
#4.2 어트리뷰트 노드의 접근/수정
-
className
-
class 어트리뷰트의 값을 취득 또는 변경
-
프로퍼티에 값을 할당하는 경우, class 어트리뷰트가 존재하지 않으면 생성 후 지정된 값을 설정
-
값이 여러 개일 경우, 공백으로 구분된 문자열이 반환
-
-
classList
- add / remove / item / toggle / contains / replace 메소드 제공
-
id
-
id 어트리뷰트의 값을 취득 또는 변경
-
프로퍼티에 값을 할당하는 경우, 존재하지 않는 경우 생성 후 지정된 값을 설정
-
-
hasAttribute(attribute)
- 지정한 어트리뷰트를 가지고 있는지 검사
- Return : Boolean
-
getAttribute(attribute)
- 어트리뷰트의 값을 취득
- Return : 문자열
-
setAttribute(attribute, value)
- 어트리뷰트와 어트리뷰트 값을 설정
- Return : undefined
-
removeAttribute(attribute)
- 지정한 어트리뷰트를 제거
- Return : undefined
#4.3 HTML 콘텐츠 조작(Manipulation)
- textContent
- 요소의 텍스트 콘텐츠 취득 또는 변경
- 마크업은 무시된다
- innerText
- 텍스트 콘텐츠에만 접근 가능
- 하지만 사용하지 않는 것을 권유
- innerHTML
- 해당 요소의 모든 자식 요소를 포함하는 모든 콘텐츠를 하나의 문자열로 취득
- 마크업을 포함
#4.4 DOM 조작 방식
innerHTML 프로퍼티를 사용하지 않고 새로운 콘텐츠를 추가할 수 있는 방법 : DOM을 직접 조작
한 개의 요소를 추가하는 경우 사용한다.
< 순서 >
-
요소 노드 생성 createElement() 메소드를 사용하여 새로운 요소 노드를 생성한다.
createElement() 메소드의 인자로 태그 이름을 전달한다. -
텍스트 노드 생성 createTextNode() 메소드를 사용하여 새로운 텍스트 노드를 생성한다.
경우에 따라 생략될 수 있지만 생략하는 경우, 콘텐츠가 비어 있는 요소가 된다. -
생성된 요소를 DOM에 추가 appendChild() 메소드를 사용하여 생성된 노드를 DOM tree에 추가한다.
또는 removeChild() 메소드를 사용하여 DOM tree에서 노드를 삭제할 수도 있다.
- createElement(tagName)
- 태그이름을 인자로 전달하여 요소를 생성
- Return : HTMLElement 를 상속받은 객체
- createTextNode(text)
- 텍스트를 인자로 전달하여 텍스트 노드를 생성
- Return : Text 객체
- appendChild(Node)
- 인자로 전달한 노드를 마지막 자식 요소로 DOM 트리에 추가
- Return : 추가한 노드
- removeChild(Node)
- 인자로 전달한 노드를 DOM 트리에서 제거
- Return : 추가한 노드
#4.5 insertAdjacentHTML()
- insertAdjacentHTML(position, string)
-
인자로 전달한 텍스트를 HTML로 파싱
-
결과로 생성된 노드를 DOM 트리의 지정된 위치에 삽입
-
#4.6 innerHTML vs DOM 조작 방식 vs insertAdjacentHTML()
- innerHTML과 insertAdjacentHTML()은 크로스 스크립팅 공격에 취약
- untrusted data의 경우, 주의
- 텍스트를 추가 또는 변경시에는 textContent 사용
- 새로운 요소의 추가 또는 삭제시에는 DOM 조작 방식 사용
#5. style
- style 프로퍼티를 사용하면 inline 스타일 선언을 생성한다.
-
style 프로퍼티의 값을 취득하려면 window.getComputedStyle을 사용한다.
const four = document.getElementById('four');
// inline 스타일 선언을 생성
four.style.color = 'blue';
// font-size와 같이 '-'으로 구분되는 프로퍼티는 카멜케이스로 변환하여 사용한다.
four.style.fontSize = '2em';
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>style 프로퍼티 값 취득</title>
<style>
.box {
width: 100px;
height: 50px;
background-color: red;
border: 1px solid black;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
const box = document.querySelector('.box');
const width = getStyle(box, 'width');
const height = getStyle(box, 'height');
const backgroundColor = getStyle(box, 'background-color');
const border = getStyle(box, 'border');
console.log('width: ' + width);
console.log('height: ' + height);
console.log('backgroundColor: ' + backgroundColor);
console.log('border: ' + border);
/**
* 요소에 적용된 CSS 프로퍼티를 반환한다.
* @param {HTTPElement} elem - 대상 요소 노드.
* @param {string} prop - 대상 CSS 프로퍼티.
* @returns {string} CSS 프로퍼티의 값.
*/
function getStyle(elem, prop) {
return window.getComputedStyle(elem, null).getPropertyValue(prop);
}
</script>
</body>
</html>
'IT 지식 기록 > JavaScript 정리' 카테고리의 다른 글
33. 이벤트 (1) | 2020.12.28 |
---|---|
32. 동기식 처리 모델 vs 비동기식 처리 모델 (0) | 2020.12.28 |
30. 배열 고차 함수 (0) | 2020.12.25 |
29. 자바스크립트 배열은 배열이 아니다 (0) | 2020.12.25 |
28. 배열 (0) | 2020.12.25 |