[학습 목표]
1. DOM의 기본 개념을 익히고, 접근 및 제어하는 방법을 통해 DOM 이해
2. Class 문법의 주요 개념(클래스, 인스턴스, getter, setter, 상속, static method 등)을 이해하고 활용
3. 클로저의 주 개념을 통해 활용하는 능력 배양
JS는 브라우저에서 쓰려고 만들어졌는데, HTML문서를 조작하여 웹 페이지를 동적으로 만들기 위한 언어이다.
사용자(=브라우저=클라이언트)가 브라우저에 www.naver.com 주소를 입력하면,
클라이언트가 서버에게 요청(request)를 보낸다.
HTML 문서를 서버로부터 수신한다.
네이버 서버가 브라우저=클라이언트에게 응답(response)을 보내는데, 그 응답은 HTML 문서(document)이다.
브라우저는 HTML 파일을 파싱(parsing: 해석)한다.
브라우저는 기본적으로 렌더링 엔진을 가지는데, 서버가 클라이언트에게 준 HTML 문서를 렌더링(번역, 칠)한다.
렌더링 엔진은 HTML 문서를 한줄 씩 보며 해석한다.
JS가 알아들을 수 있는 방식으로 해석한 내용을 토대로 DOM Tree를 구성한다.

_(출처: poiemaweb.com)
DOM Tree + CSSOM Tree 묶어서 => Render Tree를 구성한다.
렌더 트리는 HTML, CSS, JS 문서를 파싱(해석)하여 브라우저에서 실제로 렌더링되는 최중 문서 모델을 나타내는 객체의 계층 구조이다.
그러고 나서 브라우저에 그림 그리기 위한 레이아웃을 계산하고, 페인팅 과정이 시작된다.
Document(HTML 파일)를 Javascript가 알아먹을 수 있는
Object 형태로
Modeling 한 것
API는 다른 시스템에서 제공하는 기능을 사용할 수 있도록 도와주는 중간자 역할
브라우저는 기본적으로 DOM과 관련된 API를 제공함으로써 브라우저의 DOM 객체에 접근할 수 있도록 도와준다.
우리는 DOM API를 통해 DOM을 제어할 수 있다.
다음의 두 runtime 환경에서 document를 입력해보자.


실행 결과를 보면 알 수 있듯, DOM은 항상 브라우저 환경에서 돌아간다.
접근 가능제어 가능ex) 버튼을 누르면 안보이게 한다 든가 등등
JS로 HTML 요소에 접근하기 위해서는 한 가지를 더 알아야 한다.
모든 DOM의 node 들은 속성 (요소의 고유한 속성), 메소드 (노드를 제어할 수 있는 것)를 가지고 있다.
DOM에서 node란, 웹 페이지를 구성하는 모든 HTML 태그와 텍스트, 그리고 속성 등을 하나의 블록으로 취급하는 것
블록들은 서로 계층 구조로 연결되어 있다.
자식 노드, 부모 노드, 형제 노드와 관계를 가지고 있다.이런 관계를 이용하여 DOM Tree를 탐색하고 조작할 수 있다.
DOM Tree의 요소 하나 하나를 노드라고 할 수 있다.
따라서 요소 하나하나가 속성과 메서드를 가진다.

DOM의 Node 객체에서 속성과 메서드를 구분하는 가장 쉬운 방법
속성은 값을 가지고 있다.
해당 객체의 특성을 나타내는 값을 가져오거나 설정하는 데 사용
nodeName 속성은 해당 노드의 이름을 나타내는 문자열 값을 반환한다. 메서드는 동작을 수행한다.
해당 객체가 수행하는 작업을 나타내는 함수
appendChild() 메서드는 해당 노드의 자식 노드를 추가하는 메서드로, DOM 트리에서 해당 노드의 위치를 변경하는 동작을 수행한다.(동작 수행)(예시)
// 아래 코드에서 속성과 메서드를 구분해 보자!
document.getElementById("demo").innerHTML = "Hello World!";
Node 객체의 innerHTML 속성
요소(element) 내에 포함 된 HTML을 가져오거나 설정
Node 객체의 getElementById() 메서드
주어진 문자열과 일치하는 id 속성을 가진 요소를 찾고, 이를 나타내는 Element 객체를 반환하는 메서드
브라우저가 가진 DOM API 덕분에 우리는 DOM에 접근하고, 제어할 수 있다.
//돔트리의 최상단 노드는 항상 document
document.getRootNode(); // document
DOM은 모두 노드로 이루어져 있기 때문에 부모노드 - 자식노드관계로 이루어져 있다.
부모-자식 노드 사이를 왔다갔다 해 보는 연습을 통해서 익숙해 질 수 있다.
const ul = document.querySelector("#test");
document.querySelector("#test").children[0]; // li 태그
document.querySelector("#test").parentElement; // nav 태그
/** 요소 찾는 document api */
// 해당 id명을 가진 요소 하나를 반환
document.getElementById("id명")
document.getElementById("id")
// 해당 선택자를 만족하는 요소 하나를 반환
document.querySelector("선택자")
document.querySelector("#id") //🔥 id는 #을 붙여준다.
document.querySelector(".class") //🔥 class는 .을 붙여준다.
document.querySelector("태그명") //🔥 그냥 태그명 적으면 해당하는 태그 요소를 반환
// 해당 class명을 가진 요소들(pl)을 ✅ 배열에 담아 인덱스에 맞는 요소를 반환
document.getElementsByClassName("class명")[인덱스]
document.getElementsByClassName(".class")
// 해당 태그명을 가진 요소들(pl)을 ✅ 배열에 담아 인덱스에 맞는 요소를 반환
document.getElementsByTagName("태그명")[인덱스]
// 해당 선택자를 만족하는 모든 요소들(pl)을 ✅ 배열에 인덱스에 맞는 요소를 반환
document.querySelectorAll("선택자명")[인덱스]
// 새로운 노드를 생성
const div = document.createElement('div');
document.body.append(div);
document.body.append(div);

document.getElementsByClassName("class명")
해당 태그명을 가진 요소들을 배열에 담아 인덱스에 맞는 요소를 반환
document.getElementsByClassName("class명")[0]document.querySelector(".class")
해당 선택자를 만족하는 요소 하나를 반환
/** property(=속성) 바로 바꾸기 */
// 이 둘은 차이가 있음!
element.innerHTML = new html content
element.innerText = new text
// style을 바꿔요.
element.style.property = new style
//method를 통해 클래스를 추가할 수 있다.
element.setAttribute(attribute, value)
// 요소의 속성 바꾸기
element.setAttribute("style", "background-color:red;");
element.style.backgroundColor = "red";
// input 필드의 변신
innerHTML/innerText 바꿔보기


// createElements
const para = document.createElement("p");
para.innerText = "This is a paragraph";
document.body.appendChild(para);
// createTextNode(elements는 아니고, 그냥 글자)
let textNode = document.createTextNode("Hello World");
document.body.appendChild(textNode);
// write. 조심 또 조심!
// document, 즉 html 전체가 대체되어 버림
document.write("Hello World!");
document.write("<h2>Hello World!</h2><p>Have a nice day!</p>");
// 골로 가는 코드 ㅎㅎㅎㅎㅎㅎ
function myFunction() {
document.write("Hello World!");
}
// version 01
element.addEventListener("click", myFunction);
function myFunction() {
document.getElementById("#1").innerHTML = "Hello World";
}
// version 02
element.addEventListener("click", function() {
document.getElementById("#2").innerHTML = "Hello World";
});