2023-05-02(화)
Unit 10 - [JS/브라우저] DOM
------------------------------------------------------------------------------------------------------------------------------------------------
HTML을 학습할 때, HTML은 웹 페이지의 구조를 만드는 마크업 언어, 그리고 JavaScript에 대해서는
HTML로 만들어진 구조에 기능을 더 할 수 있는 프로그래밍 언어라고 설명했는데,
예를들어, HTML로 텍스트를 입력가능한 입력폼을 만들 수는 있지만, 버튼을 클릭했을 때 입력폼에 입력된
텍스트가 채팅창에 띄워지도록 하는것은 JavaScript로 해야하는 작업입니다.
Chapter1. DOM 기초
- 개념학습: 기초 개념을 학습합니다.
- 퀴즈: 학습한 개념의 이해도를 퀴즈를 통해 점검합니다.
- 해설: 퀴즈와 실습에 대해 해설하는 강의를 듣습니다.
Chapter2. DOM 다루기
- 개념학습: 기초 개념을 학습합니다.
- 퀴즈: 학습한 개념의 이해도를 퀴즈를 통해 점검합니다.
- 실습: codesandbox를 이용하여 학습한 내용을 실습합니다.
Chapter3. 이벤트 객체
- 실습: codesandbox를 이용하여 학습한 내용을 실습합니다.
------------------------------------------------------------------------------------------------------------------------------------------------
Chapter1. DOM 기초
DOM은 (Document Object Model)의 약자로, HTML 요소를 Object처럼 조작할 수 있는 모델입니다.
즉 자바크스립트를 사용할 수 있으면, DOM으로 HTML을 조작할 수 있습니다.
웹 개발자들이 모여 HTML을 분석하여 HTML의 아주 작은 부분까지 접근할 수 있는 구조를 만들었습니다.
이렇게 만들어진 구조가 DOM입니다.
DOM을 사용하여 HTML로 만들어진 웹 페이지를 동적으로 움직이게 만들 수 있습니다.
Chapter1-1. HTML에 JavaScript 적용하기
- 개념학습: DOM을 사용하여 HTML에 JavaScript를 적용하는 방법을 학습합니다.
- 퀴즈: HTML의 구조를 상기하면서, 구조를 분석합니다.
- 해설: 퀴즈에 대한 해설을 확인합니다
학습 목표
- DOM의 개념을 이해한다.
- DOM의 구조를 파악하고, HTML과 DOM이 어떻게 닮아있는지 이해한다.
- HTML에서 JavaScript 파일을 불러올 때 주의점에 대해서 이해한다.
------------------------------------------------------------------------------------------------------------------------------------------------
Chapter1-1. HTML에 JavaScript 적용하기
HTML에 JavaScript를 적용하기 위해서는 <script> 태그를 이용합니다.
웹 브라우저가 작성된 코드를 해석하는 과정에서 <script> 요소를 만나면, 웹 브라우저는 HTML 해석을 잠시 멈춥니다. HTML 해석을 잠시 멈춘 웹 브라우저는 <script> 요소를 먼저 실행합니다.
<script> 요소는 등장과 함께 실행이 됩니다. 이 요소를 추가하는 방법은 2가지가 있는데
1. <head> 안쪽에 삽입하는 경우
2. <body> 요소가 끝나기 전에 삽입하는 경우
두 방식의 공통점과 차이점
두 방식 모두 myScriptFile.js 내의 첫 번째 console.log를 성공적으로 출력하지만,
두 번째 console.log의 경우 제대로 출력하지 못하는 예시가 있습니다.
console.log('welcome JavaScript');
let msgElement = document.querySelector('#msg');
console.log(msgElement);
Q. 질문
- 각 방법은 콘솔 출력이 어떻게 다른가요?
- 1번 방법에서는 null 이 콘솔에 출력되는 이유가 무엇일까요?
- HTML 요소를 이용하려면 1번과 2번 중 어떤 방법을 사용해야 할까요?
= 이로인해 HTML태그들 사이에 script 태그가 위치하면 두가지 문제가 발생합니다.
- HTML을 읽는 과정에 스크립트를 만나면 중단 시점이 생기고 그만큼 Display에 표시되는 것이 지연된다.
- DOM 트리가 생성되기전에 자바스크립트가 생성되지도 않은 DOM의 조작을 시도할 수 있다.
위와 같은 상황을 막기 위해 script 태그는 body 태그 최하단에 위치하는 게 가장 좋습니다.
<html>
<body>
<div id="nav">
<div class="logo"></div>
<div class="menu-wrapper">
<div class="menu"></div>
<div class="menu"></div>
<div class="menu"></div>
<div class="profile-photo"></div>
</div>
</div>
<div id="news-contents">
<div class="news-content-wrapper">
<div class="news-picture"></div>
<div class="news-title"></div>
<div class="news-description"></div>
</div>
</div>
<div id="footer"></div>
</body>
</html>
- 여기서 body 엘리먼트의 자식 엘리먼트(element)는 총 몇 개인가?
- class의 이름이 news-contents 인 div 엘리먼트의 부모 엘리먼트는 무엇인가?
- id의 이름이 nav인 div엘리먼트 를 포함해서, 모든 자식 엘리먼트의 class 이름을 console.log를 사용하여 확인하려면 어떻게 해야 할지 수도코드(pseudocode)를 작성하라.
1. 자식 엘리먼트 찾기
위에서 내린 3개의 질문 중 첫번째 질문에 대한 답변은 바로 3개이다.
body 엘리먼트의 자식 엘리먼트는 총 3개이다.
id가 nav, news-contents, footer 인 3가지 엘리먼트이다.
그럼 자바스크립트는 어떻게 인식할까?
자바스크립트에서 DOM은 document 객체에 구현되어 있다.
브라우저에서 작동하는 자바스크립트 코드에서는 어디에서나 document객체를 조회할 수 있다.
DOM 구조를 조회하기 위해서는 console.dir이 유용하다. console.dir은 console.log와 달리 DOM을 객체의 모습으로 보여준다.
console.dir을 이용해 document.body를 조회해 보니, 너무나 많은 속성이 나타납니다. 앞서 학습한 내용을 상기해 보면, HTML 엘리먼트에 지정할 수 있었던 다양한 속성이 이미 객체 내에 존재한다고 생각하면 됩니다.
여기서 자식 엘리먼트를 찾아보자.
children을 찾아보면
console.dir(document.body)를 통해 출력된 객체에서, children 속성을 찾을 수 있습니다. children 속성에 nav, news-contents, footer 가 자식으로 있는 것을 확인할 수 있습니다. 물론 document.body.children으로 바로 조회할 수도 있습니다.
2. 부모 엘리먼트 찾기
두번째 질문의 답은 body이다.
자바스크립트에서도 확인할 수 있는데, document.body.children의 첫번째 엘리먼트를 조회해보자.
첫번째 엘리먼트가 div#news-contents라고 나온다.
여기서 매번 document.body로 찾아가는건 매번 번거로우므로 따로 변수 newsContents를 선언을 해서 저장해둘 수 있다.
Q: 그렇다면, newsContents의 부모 요소를 가리키는 속성을 찾기 위해서는 콘솔창에 무엇을 입력해야할까?
A: console.dir(newsContents.parentElement)
3. DOM 순회하기
DOM 구조의 특성을 보면 조직도가 생각나게끔 한다.
부모가 자식을 여러개 가지고, 부모가 하나인 구조가 계속 반복된다.
이런 자료 구조를 컴퓨터 공학에서는 트리 구조라고 합니다. 트리 구조의 가장 큰 특징은 부모가 자식을 여러 개 가지고, 부모가 하나인 구조가 반복되는 점입니다. 즉, 부모가 가진 하나 또는 여러 개의 자식 엘리먼트를 조회하는 코드를 작성한다면, 여러 번 반복해서 실행하는 코드가 필요합니다.
function consoleLogAllElement(element){
// nav의 class 이름을 console.log 합니다.
// nav의 자식 엘리먼트가 있는지 검색합니다. (logo, menu-wrapper)
//logo의 class 이름을 console.log 합니다.
//logo의 자식 엘리먼트가 있는지 검색합니다. (없음)
//menu-wrapper의 class 이름을 console.log 합니다.
//menu-wrapper의 자식 엘리먼트가 있는지 검색합니다. (menu, menu, menu, profile-photo)
//첫 번째 menu의 class 이름을 console.log 합니다.
//첫 번째 menu의 자식 엘리먼트가 있는지 검색합니다. (없음)
//두 번째 menu의 class 이름을 console.log 합니다.
//두 번째 menu의 자식 엘리먼트가 있는지 검색합니다. (없음)
//세 번째 menu의 class 이름을 console.log 합니다.
//세 번째 menu의 자식 엘리먼트가 있는지 검색합니다. (없음)
//profile-photo의 class 이름을 console.log 합니다.
//profile-photo의 자식 엘리먼트가 있는지 검색합니다 (없음)
//자식 엘리먼트를 모두 탐색했음으로, 함수 실행이 종료됩니다.
//자식 엘리먼트를 모두 탐색했음으로, 함수 실행이 종료됩니다.
}
------------------------------------------------------------------------------------------------------------------------------------------------
Chapter2. DOM 다루기
document 객체에는 많은 속성과 메서드가 존재합니다.
지금 집중할 부분은 CRUD(Create, Read, Update and Delete)입니다.
앞으로 어떤 종류의 개발이나 컴퓨터 언어를 배우시더라도 가장 먼저 CRUD에 집중해야 합니다.
CRUD를 먼저 이해하는 것이 새로운 언어를 가장 빠르게 학습하는 방법입니다. (CRUD를 이해한 다음에는 세세한 메서드들을 알아야 합니다.)
document 객체를 통해서 HTML 엘리먼트를 만들고(CREATE), 조회하고(READ), 갱신하고(UPDATE), 삭제하는(DELETE) 방법을 학습합니다.
DOM에는 HTML에 적용(APPEND)하는 메서드가 따로 있으니 주의하세요!
학습 목표
- DOM을 JavaScript로 조작하여 HTML Element를 추가할 수 있다. (CREATE)
- DOM을 JavaScript로 조작하여 HTML Element를 조회할 수 있다. (READ)
- DOM을 JavaScript로 조작하여 HTML Element를 변경할 수 있다. (UPDATE)
- DOM을 JavaScript로 조작하여 HTML Element를 삭제할 수 있다. (DELETE)
- 생성한 HTML Element를 부모 엘리먼트의 자식 엘리먼트로 포함할 수 있다. (APPEND)
- innerHTML과 textContent의 차이를 이해한다.
Chapter2-1. CREATE
DOM을 이용하여 HTML Element를 추가하는 방법을 실습합니다.
document.createElement(HTML요소)
지정된 HTML 요소를 생성한다.
ex)
document.createElement('div')
<div></div>
Chapter2-2. APPEND
.append()
해당 노드에 새로운 요소를 부여한다.
위에서 생성한 요소 document.createElement('div')를 변수로 선언하여 결과로 할당하여
let tweetDiv = document.createElement('div') 를 만들었다.
body에 선언했던 변수 요소를 넣는다고하면
document.body.append(tweetDiv) 라고 쓴다.
append() 와 appendChild() 의 차이점
append()appendChild()
자바스크립트 메소드 | DOM 메소드 |
문자열, 텍스트 노드, 엘리먼트 노드 삽입 가능 | 노드 객체만 삽입 가능 |
노드 갯수 여러개 허용 | 노드 갯수 하나만 허용 |
append()와 prepend()의 차이점
append()prepend()
컨텐츠를 선택된 요소 내부의 끝 부분에서 삽입 | 컨텐츠를 선택한 요소 내부의 시작 부분에서 삽입 |
ex)
<p>코딩</p> 이렇게 있을 경우
append()는 <p>코딩 여기에값이들어간다.</p>
prepend()는 <p>여기에값이들아간다. 코딩</p>
Chapter2-3. READ
document.querySelector()
특정 선택자(id나 class)를 가진 첫번째 요소를 선택한다.
- id 태그를 조회할 때는 이름 앞에 #을 붙힌다.
ex) document.querySelector('#tweet') - class 태그를 조회할 때는 이름 앞에 .을 붙힌다.
ex) document.querySelector('.tweet')
document.querySelectorAll()
특정 선택자(id나 class)를 가진 모든 요소를 선택한다.
- id 태그를 조회할 때는 이름 앞에 #을 붙힌다.
ex) document.querySelectorAll('#tweet') - class 태그를 조회할 때는 이름 앞에 .을 붙힌다.
ex) document.querySelectorAll('.tweet')
Chapter2-4. UPDATE
.textContent
태그 사이에 내용을 넣는다.
ex) tweetDiv.textContent = 'Yeonlisa'; // <div>Yeonlisa</div>
.classList.add()
해당 태그에 클래스를 지정한다.
ex) tweetDiv.classList.add('tweet'); // <div class="tweet">Yeonlisa</div>
textContent와 innerHTML의 차이
textContent
요소의 텍스트 콘텐츠를 취득 또는 변경한다. 이때 마크업은 무시된다.
textContent를 통해 요소에 새로운 텍스트를 할당하면 텍스트를 변경할 수 있다.
이때 순수한 텍스트만 지정해야 하며 마크업을 포함시키면 문자열로 인식되어 그대로 출력된다.
innerHTML
해당 요소의 모든 자식 요소를 포함하는 모든 콘텐츠를 하나의 문자열로 취득할 수 있다.
이 문자열은 마크업을 포함한다.
innerHTML의 보안상 단점
XSS(Cross-Site Scripting) 공격에 취약하다.
Chapter2-5. DELETE
.remove()
태그를 삭제한다.
let container = document.querySelector('#container')
let tweetDiv = document.createElement('div') // <div></div>
container.append(tweetDiv) // 부모인 container 에 tweetDiv 를 넣는다.
tweetDiv.remove() // 이렇게 append 했던 엘리먼트를 삭제할 수 있다.
.removeChild()
태그의 자식만 삭제한다.
const container = document.querySelector('#container');
while (container.children.length > 1) {
container.removeChild(container.lastChild);
} // 자식을 하나만 남겨두고 모두 제거한다.
remove()와 removeChild()의 차이점
remove() 는 노드를 메모리에서 삭제하고 종료한다.
removeChild()는 노드를 삭제하는 것이 아니라 메모리에 해당 노드는 그대로 존재하며, 부모 노드와의 부모-자식관계를 끊어 DOM 트리에서 해제하는 것이다.
그외
element와 node의 차이점
node는 element의 상위 개념이다.
children과 childNodes의 차이점
children은 현재 요소의 자식 요소가 포함된 HTML Collection을 반환한다.(자식 요소에 접근)
childNodes는 현재 요소의 자식 노드가 포함된 NodeList를 반환한다.(자식 노드에 접근)
'Section1' 카테고리의 다른 글
코드스테이츠 프론트엔드 부트캠프 18일차 (0) | 2023.05.04 |
---|---|
코드스테이츠 프론트엔드 부트캠프 17일차 (0) | 2023.05.03 |
코드스테이츠 프론트엔드 부트캠프 15일차 (0) | 2023.05.01 |
코드스테이츠 프론트엔드 부트캠프 14일차 (0) | 2023.04.28 |
코드스테이츠 프론트엔드 부트캠프 13일차 (0) | 2023.04.27 |