호스트 환경이 웹 브라우저일 때 사용할 수 있는 기능
DOM | BOM | JavaScript |
---|---|---|
document | navigator | Object |
screen | Array | |
location | Function | |
frames | ||
history | ||
XMLHttpRequest |
window
라 불리는 루트
객체가 있다window
객체의 역할브라우저 창
을 대변하고, 이를 제어할 수 있는 메서드를 제공document
객체를 이용해 페이지 내 무엇이든 변경할 수 있고, 생성할 수 있다.// 배경을 붉은색으로 변경하기 document.body.style.background = "red";
문서 객체 모델(DOM)에 따르면 모든 HTML 태그는 객체이다.
이런 모든 객체는 자바스크립트를 통해 접근할 수 있고, 페이지를 조작할 때 이 객체를 사용한다.
document.body
는 <body>
태그를 객체로 나타낸 것
<!DOCTYPE HTML>
<html>
<head>
<title>사슴에 관하여</title>
</head>
<body>
사슴에 관한 진실.
</body>
</html>
트리 구조로 표현하면
설명)
트리에 있는 노드는 모두 객체
<HTML>
은 루트 노드가 되고, <HEAD>
와 <BODY>
는 루트 노드
의 자식이 된다.
요소 내의 문자는 텍스트 노드
가 된다.
텍스트 노드
는 문자열만 담는다.
자식 노드를 가질 수 없고 leaf node가 된다.
(새줄) 과 (공백)은 글자나 숫자처럼 항상 유효한 문자로 취급된다.
이 두 특수문자는 텍스트 노드가 되고 DOM의 일부가 된다.
텍스트 노드 생성 시 예외 2가지
역사적인 이유로, <head>
이전의 공백과 새 줄은 무시
HTML 명세서에서 모든 콘텐츠는 body 안쪽에 있어야 한다고 했으므로, </body>
뒤에 무언가를 넣더라도 그 콘텐츠는 자동으로 body 안쪽으로 옮겨진다. </body>
뒤에는 공백이 있을 수 없다.
공백이 없는 텍스트 노드만으로 HTML 문서를 구성하려면 아래와 같이 만들어야 함
<!DOCTYPE HTML>
<html><head><title>사슴에 관하여</title></head><body>사슴에 관한 진실.</body></html>
cf ) 문자열 양 끝 공백과 공백만 있는 텍스트 노드는 개발자 도구에서 보이지 않는다.
기형적인 HTML을 만나면 브라우저는 DOM 생성과정에서 HTML을 자동으로 교정한다.
ex) 문서에 <html>
태그가 없는 경우, 문서 최상위에 이를 자동으로 넣어준다.
주석도 노드 타입 #comment
HTML 문서 최상단에 위치하는 <!DOCTYPE...>
지시자 또한 DOM 노드
노드 타입은 총 열두 가지 인데, 실무에선 주로 다음 네 가지 노드를 다룬다.
(document)
노드요소 노드(element node)
텍스트 노드(text node)
주석(comment) 노드
DOM에서 수행하는 모든 연산은 document 객체에서 시작한다.
document 객체는 DOM에 접근하기 위한 '진입점'이다.
진입점을 통과하면 어떤 노드에도 접근할 수 있다.
<html> = document.documentElement
<body> = document.body
<head> = document.head
<html>
<body>
<div>시작</div>
<ul>
<li>
<b>항목</b>
</li>
</ul>
</body>
</html>
<body>
의 자식 노드: <div>
와 <ul>
, 몇 개의 빈 텍스트 노드
<body>
의 후손 노드: <div>
나 <ul>
같은 <body>
의 자식 요소뿐만 아니라 <ul>
의 자식 노드인 <li>
와 <b>
같이 더 깊은 곳에 있는 중첩 요소도 포함
childNodes 컬렉션
은 텍스트 노드
를 포함한 모든 자식 노드를 담고 있습니다.
EX ) document.body의 자식 노드가 출력됩니다.
<html>
<body>
<div>시작</div>
<ul>
<li>항목</li>
</ul>
<div>끝</div>
<script>
for (let i = 0; i < document.body.childNodes.length; i++) {
alert( document.body.childNodes[i] );
// Text, DIV, Text, UL, ... , SCRIPT
}
</script>
...추가 내용...
</body>
</html>
firstChild와 lastChild 프로퍼티를 이용해
첫 번째, 마지막 자식 노드에 빠르게 접근할 수 있다.
elem.childNodes[0] === elem.firstChild
elem.childNodes[elem.childNodes.length - 1] === elem.lastChild
childNodes
는 마치 배열 같아 보인다.
하지만 childNodes
는 배열이 아닌 반복 가능한(iterable, 이터러블) 유사 배열 객체인 컬렉션(collection)
이다.
1.for..of를 사용할 수 있습니다.
for (let node of document.body.childNodes) {
alert(node);
// 컬렉션 내의 모든 노드를 보여줍니다.
}
2.배열이 아니기 때문에 배열 메서드를 쓸 수 없습니다.
alert(document.body.childNodes.filter);
// undefined (filter 메서드가 없습니다.)`
컬렉션
에 배열 메서드를 사용하고 싶다면 Array.from
을 적용합시다.
alert( Array.from(document.body.childNodes).filter ); // function
같은 부모를 가진 노드는 형제(sibling) 노드
ex)
<head>
와<body>
는 대표적인 형제 노드
다음 형제 노드에 대한 정보는 nextSibling, 이전 형제 노드에 대한 정보는 previousSibling 프로퍼티에서 찾을 수 있다.
부모 노드에 대한 정보는 parentNode 프로퍼티를 이용해 참조할 수 있다.
children 프로퍼티는 해당 요소의 자식 노드 중 요소 노드만을 가리킵니다.
firstElementChild와 lastElementChild 프로퍼티는 각각 첫 번째 자식 요소 노드와 마지막 자식 요소 노드를 가리킵니다.
previousElementSibling과 nextElementSibling은 형제 요소 노드를 가리킵니다.
parentElement 는 부모 요소 노드를 가리킵니다.
<table>
요소는 기본 프로퍼티 이외에 다음과 같은 프로퍼티를 지원
table.rows는 <tr>
요소를 담은 컬렉션을 참조
table.caption/tHead/tFoot은 각각 <caption>
, <thead>
, <tfoot>
요소를 참조
table.tBodies는 <tbody>
요소를 담은 컬렉션을 참조
HTML 문서에는 <tbody>
가 없더라도 브라우저는 <tbody>
노드를 DOM에 자동으로 추가
<thead>
, <tfoot>
, <tbody>
요소는 rows 프로퍼티를 지원
tbody.rows는 tbody 내 <tr>
요소 컬렉션을 참조
<tr>
요소는 다음 프로퍼티를 지원합니다.
tr.cells는 주어진 <tr>
안의 모든 <td>
, <th>
을 담은 컬렉션을 반환
tr.sectionRowIndex는 주어진 <tr>
이 <thead>/<tbody>/<tfoot>
안쪽에서 몇 번째 줄에 위치하는지를 나타내는 인덱스를 반환
tr.rowIndex는 <table>
내에서 해당 <tr>
이 몇 번째 줄인 지를 나타내는 숫자를 반환
<td>
와 <th>
요소는 다음 프로퍼티를 지원
td.cellIndex는 <td>
나 <th>
가 속한 <tr>
에서 해당 셀이 몇 번째인지를 나타내는 숫자를 반환
탐색 프로퍼티를 사용하면 이웃 노드로 바로 이동할 수 있습니다.
탐색 프로퍼티는 크게 두 개의 집합으로 나뉩니다.
- 모든 노드에 적용 가능한
parentNode, childNodes, firstChild, lastChild, previousSibling, nextSibling
- 요소 노드에만 적용 가능한
parentElement, children, firstElementChild, lastElementChild, previousElementSibling, nextElementSibling
<html>
<body>
<div>사용자:</div>
<ul>
<li>John</li>
<li>Pete</li>
</ul>
</body>
</html>
아래 DOM 노드에 접근할 방법을 최소 한 가지 이상씩 생각해보세요.
<div>
DOM 노드 :
document.body.firstElementChild
document.body.children[0]
document.body.chilNodes[1]
<ul>
DOM 노드:
document.body.children[1]
document.body.firstElementChild.nextElementSibling
document.body.lastElementChild
두 번째 <li>
(Pete):
document.body.lastElementChild.lastElementChild
let table = document.body.firstElementChild;
for(let i=0;i<5;i++){
let td=table.rows[i].cells[i]
td.style.backgroundColor='red';
}