모던 자바스크립트 Deep Dive 글 목록(스터디)
https://hello-kk.tistory.com/780
DOM(Document Object Model): 노드 객체로 구성된 트리 자료구조
- 이를 제어할 수 있는 API, 즉 프로퍼티와 메서드를 제공하는 트리 자료구조
- DOM이 제공하는 프로퍼티와 메서드를 사용하여 노드에 접근, HTML의 구조와 내용 또는 스타일 등을 동적으로 변경하는 방법을 익히는 것이 중요
Element: Tag?
요소 노드 == 태그
중첩 관계
비선형 자료구조: 하나의 자료 뒤에 여러 개의 자료가 존재할 수 있는 자료구조
DOM API를 통해
(1) 자신의 부모, 형제, 자식 탐색 가능
(2) 자신의 어트리뷰트와 텍스트를 조작 가능
live DOM 컬렉션 객체
: 실시간으로 노드 객체의 상태 변경을 반영하여 요소를 제거하기 때문에, 상태를 변경할 때 주의해야 한다.
해결방법
[ ... $elements] 배열로 변환하기!
(혹은, for문을 역방향으로 순회함으로 회피가능)
비구조화 할당 활용하여 추출 가능
const $fruites = document.getElementById('fruits')
const {firstChild} = $fruits;
DOM은 파싱 이후 트리구조를 갖는다.
DOM API
(1) 어떤 노드를 탐색할 것인지
● 요소 노드 취득하는 방법: 태그 이름, class 이름, CSS 선택자
● 요소 노드를 취득할 수 있는지 true/false
(2) 반환된 요소 노드 리스트에서, (배열로 변환한 뒤 활용할 것!)
(3) 해당 노드의 부모 노드를? 형제 노드를? 자식 노드를? 탐색할 것인지
(4) 어트리뷰트 또는 텍스트를 조작할 것인지
● nodeValue
● textContent
탐색 시간에 따라, 어떤 프로퍼티를 사용할지 달라진다.
39.1 노드
39.1.1 HTML 요소와 노드 객체
HTML element: HTML 문서를 구성하는 개별적인 요소
HTML 요소는 렌더링 엔진에 의해 파싱되어 DOM을 구성하는 요소 노드 객체로 변환
어트리뷰트 → 어트리뷰트 노드
텍스트 콘텐츠 → 텍스트 노드
<div class = “greeting”>Hello</div>
중첩 관계 → 계층적인 부자 관계 형성(parent-child)
트리 자료구조
비선형 자료구조(하나의 자료 뒤에 여러 개의 자료가 존재할 수 있는 자료구조)
39.1.2 노드 객체의 타입
노드 타입
문서 노드 | document 객체 | DOM 트리 최상위 루트 노드 |
요소 노드 | HTML 요소를 가리키는 객체 | 중첩에 의한 부자 관계 |
어트리뷰트 노드 | 요소 노드와 연결(단, 부모 노드는 없기 때문에 요소 노드의 형제 노드는 아님) | |
텍스트 노드 | 요소 노드의 자식노드 리프노드 |
39.1.3 노드 객체의 상속 구조
DOM API를 통해
(1) 자신의 부모, 형제, 자식 탐색 가능
(2) 자신의 어트리뷰트와 텍스트를 조작 가능
DOM을 구성하는 노드는 빌트인 객체가 아니라, 브라우저 환경에서 추가적으로 제공하는 호스트 객체
상속 구조
모든 노드 객체는 Object, EventTarget, Node 인터페이스를 상속받는다
Node 인터페이스를 상속받아 모든 노드 객체는 트리 탐색 기능, 노드 정보 제공 기능이 가능하다
공통된 기능일수록 프로토타입 체인 상위에 위치한다
개별 고유 기능일수록 프로토타입 체인 하위에 프로토타입 체인을 구축.
39.2 요소 노드 취득
동적으로 조작하기 위한 첫번째 방법
39.2.1 id를 이용한 요소 노드 취득
● id는 유일한 값
Document.prototype.getElementById
● id가 여러개라면 첫번째 요소 노드만 반환
39.2.2 태그 이름을 이용한 요소 노드 취득
getElementsByTagName 메서드
Elements => 복수형
만약, document.getElementsByTagName('*')을 하게 되면, HTML 문서의 모든 요소 노드를 취득 가능
Document.prototype.getElementsByTagName | Element.prototype.getElementsByTagName |
document 를 통해 호출 document.getElementsByTagName DOM 전체에서 요소 노드를 탐색하여 반환 |
특정 노드를 통해 호출 $value.getElementsByTagName 특정 요소 노드의 자손 노드 중에서 노드를 탐색하여 반환 |
39.2.3 class를 이용한 요소 노드 취득
Document.prototype.getElementsByClassName
Element.prototype.getElementsByClassName
공백으로 구분하여 여러 개의 class 지정 가능
예시: Document.prototype.getElementsByClassName("fruit apple")
39.2.4 CSS 선택자를 이용한 요소 노드 취득
Document.prototype/Element.prototype.querySelector
Document.prototype/Element.prototype.querySelectorAll
★ CSS 선택자 문법은 getElementBy~ 메서드보다 느리다
따라서, id 어트리뷰트가 있는 요소 노드를 취득하는 경우는 getElementById 메서드를 사용하기
그 외의 경우는 quertSelector,querySelectorAll 사용하기
39.2.5 특정 요소 노드를 취득할 수 있는지 확인
Element.prototype.matches
이벤트 위임을 사용할 때
39.2.6 HTMLCollection과 NodeList
두 개념 모두 유사 객체 배열이면서 이터러블
for문으로 순회하며 요소 값을 변경
live DOM 컬렉션 객체
HTMLCollection
- getElementsByTagName가 반환
- getElementsByClassName가 반환
live DOM 컬렉션 객체
: 실시간으로 노드 객체의 상태 변경을 반영하여 요소를 제거하기 때문에, 상태를 변경할 때 주의해야 한다.
0번째 노드를 변경해서, 0번 인덱스 요소가 배열에서 삭제된다(popleft). 따라서, 1번 인덱스 요소가 0번 위치로 이동하기 때문에 아직 바뀌지 않은 0번 인덱스를 수정하지 않고 넘기는 것
(1) for문을 역방향으로 순회함으로 회피가능
(2) [ ... $elements] 배열로 변환하기. 고차 함수도 사용 가능하다
NodeList
querySelectorAll
non-live DOM 컬렉션 객체
과거의 정적 상태를 유지함
하지만, childNodes 프로퍼티가 반환하는 NodeList 객체는 live 객체로 동작
해결방법
[ ... $elements] 배열로 변환하기!
39.3 노드 탐색
모두 (읽기 전용) 접근자 프로퍼티
39.3.1 공백 텍스트 노드
스페이스, 탭, 줄바꿈(개행)
39.3.2 자식 노드 탐색
Node.prototype.childNodes | 자식 노드 모두 탐색 요소노드, 텍스트 노드 NodeList 반환 |
Element.prototype.children | 자식 노드 중 요소 노드만 탐색 HTMLCollection에 담아 반환 |
Node.prototype.firstChild | 첫번째 자식 노드 반환 요소노드 또는 텍스트 노드 |
Node.prototype.lastChild | 마지막 자식 노드 반환 요소노드 또는 텍스트 노드 |
Element.prototype.firstElementChild | 첫번째 자식 노드 반환 요소노드만 반환 |
Element.prototype.lastElementChild | 마지막 자식 노드 반환 요소노드만 반환 |
39.3.3 자식 노드 존재 확인
Node.prototype.hasChildNodes
반환 값: true/false
(요소노드와 텍스트노드)
자식 노드 중 텍스트 노드가 아닌 노드가 존재하는지 확인
children.length 또는 childElementCount
39.3.4 요소 노드의 텍스트 노드 탐색
firstChild 프로퍼티
39.3.5 부모 노드 탐색
Node.prototype.parentNode
텍스트 노드가 반환되지 않는다.(선택한 노드의 부모 노드는 텍스트 노드가 될 수 없다)
39.3.6 형제 노드 탐색
Node.prototype.previousSibling
Node.prototype.nextSibling
Element.prototype.previousElementSibling
Element.prototype.nextElementSibling
const $fruites = document.getElementById('fruits')
const {firstChild} = $fruits;
39.4 노드 정보 취득
Node.prototype.nodeType
Node.prototype.nodeName
39.5 요소 노드의 텍스트 조작
39.5.1 nodeValue
setter/ getter
노드 객체의 값 반환.(텍스트 노드의 텍스트 반환)
=> 요소 노드의 경우 null을 반환
(1) 텍스트를 변경할 요소 노드 취득
(2) 취득한 요소 노드의 텍스트 노드 탐색
(3) 텍스트 노드는 요소 노드의 자식 노드이므로 fistChild 프로퍼티 사용하여 탐색
(4) 탐색한 텍스트 노드의 nodeValue 프로퍼티를 사용하여 텍스트 노드의 값 변경
39.5.2 textContent
요소 노드의 텍스트와 모든 자손 노드의 텍스트를 모두 취득하거나 변경
(1) 탐색의 경우
텍스트만 모두 반환(마크업 생략)
(2) 할당의 경우
자식 노드가 모두 제거되고, '문자열'이 텍스트로 추가된다(마크업이 포함되더라도, 문자열로 그대로 출력=마크업이 파싱되지 않는다)
nodeValue 보다 textContent를 사용하는 편이 더 간단한 것 같다.
innerText 프로퍼티를 사용하는 것이 좋지 않은 이유
- CSS에 순종적이기 때문에, visibility: hidden인 경우 지정된 요소 노드의 텍스트를 반환하지 않는다
- CSS를 고려해야 하므로 textContent 프로퍼티보다 느리다
'Front-End > JavaScript' 카테고리의 다른 글
40장 이벤트 (모던 자바스크립트 Deep Dive) (0) | 2023.05.28 |
---|---|
39장 DOM (모던 자바스크립트 Deep Dive) (0) | 2023.05.25 |
38장 브라우저 렌더링 과정/33장 Symbol/48장 모듈 (모던 자바스크립트 Deep Dive) (0) | 2023.05.18 |
37장 Set과 Map (모던 자바스크립트 Deep Dive) (1) | 2023.05.15 |
25장 클래스 (모던 자바스크립트 Deep Dive) (0) | 2023.05.10 |