브라우저: 문서

김지원·2020년 11월 2일
0

JavaScript

목록 보기
5/21

파트2의 일부를 정리한 글 입니다.

1.1 브라우저 환경과 다양한 명세서

호스트 환경이 웹 브라우저일 때 사용할 수 있는 기능

window

DOMBOMJavaScript
documentnavigatorObject
screenArray
locationFunction
frames
history
XMLHttpRequest
  • 최상단엔 window라 불리는 루트 객체가 있다
  • window 객체의 역할
    • 자바스크립트 코드의 전역 객체이다
    • 브라우저 창을 대변하고, 이를 제어할 수 있는 메서드를 제공

문서 객체 모델(DOM)

  • 웹 페이지 내의 모든 콘텐츠를 객체로 나타내준다.
  • document 객체를 이용해 페이지 내 무엇이든 변경할 수 있고, 생성할 수 있다.
    // 배경을 붉은색으로 변경하기 document.body.style.background = "red";

브라우저 객체 모델(BOM)

  • 문서 이외의 모든 것을 제어하기 위해 브라우저(호스트 환경)가 제공하는 추가 객체
  • navigater 객체: 브라우저와 운영체제에 대한 정보를 제공
  • location 객체: 현재 URL을 읽을 수 있게 해주고 새로운 URL로 변경할 수 있게 해준다.

1.2 DOM 트리

문서 객체 모델(DOM)에 따르면 모든 HTML 태그는 객체이다.

이런 모든 객체는 자바스크립트를 통해 접근할 수 있고, 페이지를 조작할 때 이 객체를 사용한다.

document.body<body> 태그를 객체로 나타낸 것

DOM 구조

<!DOCTYPE HTML>
<html>
<head>
  <title>사슴에 관하여</title>
</head>
<body>
  사슴에 관한 진실.
</body>
</html>

트리 구조로 표현하면

  • HTML
    • HEAD
      • #text (새줄)
      • TITLE
        • #text 사슴에 관하여
      • #text (새줄)
    • #text (새줄)
    • BODY
      • #text 사슴에 관한 진실.

설명)
트리에 있는 노드는 모두 객체
<HTML>은 루트 노드가 되고, <HEAD><BODY>루트 노드의 자식이 된다.

요소 내의 문자는 텍스트 노드가 된다.
텍스트 노드는 문자열만 담는다.
자식 노드를 가질 수 없고 leaf node가 된다.

(새줄) 과 (공백)은 글자나 숫자처럼 항상 유효한 문자로 취급된다.
이 두 특수문자는 텍스트 노드가 되고 DOM의 일부가 된다.

텍스트 노드 생성 시 예외 2가지

  1. 역사적인 이유로, <head> 이전의 공백과 새 줄은 무시

  2. 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 노드

노드 타입은 총 열두 가지 인데, 실무에선 주로 다음 네 가지 노드를 다룬다.

  1. DOM의 '진입점"이 되는 문서(document) 노드
  2. HTML 태그에서 만들어지며, DOM 트리를 구성하는 블록인 요소 노드(element node)
  3. 텍스트를 포함하는 텍스트 노드(text node)
  4. 화면에 보이지는 않지만, 정보를 기록하고 자바스크립트를 사용해 이 정보를 DOM으로부터 읽을 수 있는 주석(comment) 노드

1.3 DOM 탐색하기

DOM에서 수행하는 모든 연산은 document 객체에서 시작한다.
document 객체는 DOM에 접근하기 위한 '진입점'이다.
진입점을 통과하면 어떤 노드에도 접근할 수 있다.

<html> = document.documentElement
<body> = document.body
<head> = document.head

childNodes, firstChild, lastChild로 자식 노드 탐색하기

  • 자식 노드(child node, children): 바로 아래의 자식 요소를 나타낸다.
  • 후손 노드(descendants): 중첩 관계에 있는 모든 요소를 의미한다. 자식 노드, 자식 노드의 모든 자식노드 등이 후손 노드
<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

DOM 컬렉션

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
  • DOM 컬렉션은 읽는 것만 가능합니다.
  • elem.childNodes를 참조하고 있는 도중에 DOM에 새로운 노드가 추가되거나 삭제되면, 변경사항이 컬렉션에도 자동으로 반영됩니다.
  • 컬렉션에 for..in 반복문을 사용하지 마세요,

형제와 부모 노드

같은 부모를 가진 노드는 형제(sibling) 노드

ex) <head><body>는 대표적인 형제 노드

  • 다음 형제 노드에 대한 정보는 nextSibling, 이전 형제 노드에 대한 정보는 previousSibling 프로퍼티에서 찾을 수 있다.

  • 부모 노드에 대한 정보는 parentNode 프로퍼티를 이용해 참조할 수 있다.

  • children 프로퍼티는 해당 요소의 자식 노드 중 요소 노드만을 가리킵니다.

  • firstElementChildlastElementChild 프로퍼티는 각각 첫 번째 자식 요소 노드와 마지막 자식 요소 노드를 가리킵니다.

  • previousElementSiblingnextElementSibling형제 요소 노드를 가리킵니다.

  • 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

과제 1

<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

과제 2

  let table = document.body.firstElementChild;

    for(let i=0;i<5;i++){
      let td=table.rows[i].cells[i]
      td.style.backgroundColor='red';
    }

0개의 댓글