- amplify
- CF
- 모던자바스크립트DeepDive
- eslint
- javascirpt
- SSH
- AWS
- preload
- Prefetch
- fetchpriority
- 백준
- 프로그래머스
- TypeScript
- IntersectionObserverAPI
- JavaScript
- Algorithm
- nuxt
- 자바스크립트
- 캐시무효화
- html
- composition api
- github
- S3
- programmers
우주선
모던 자바스크립트 Deep Dive ― (10) 본문
모던 자바스크립트 Deep Dive ― (10)
39장 DOM
DOM 은 HTML 문서의 계층적 구조와 정보를 표현하며 이를 제어할 수 있는 API, 프로퍼티와 메서드를 제공하는 트리 자료구조다.
39.1 노드
HTML 요소는 HTML 문서를 구성하는 개별적인 요소를 의미한다. 이 요소는 렌더링 엔진에 의해 파싱되어 DOM을 구성하는 요소 노드 객체로 변환된다. DOM을 구성하는 노드 객체는 ECOMScript에 정의된 게 아니라 브라우저 환경에서 추가적으로 제공하는 호스트 객체이다.
1) 트리 자료구조
- 노드들의 계층 구조로 이뤄진다.
- 부모 노드와 자식 노드로 구성되어 노드 간의 계층적 구조를 표현하는 비선형 자료구조다.
- 최상위 노드를 루트 노드, 자식 노드가 없으면 리프 노드라 한다.
- 노드 객체들로 구성된 트리 자료구조를 DOM 트리라고 한다.
2) 노드 객체의 타입
- 문서 노드 : DOM트리의 최상위에 존재하는 루트 노드, document객체
- 요소 노드 : HTML 요소를 가리키는 객체
- 어트리뷰트 노드 : HTML요소의 어트리뷰트를 가리키는 객체
- 텍스트 노드 : HTML 요소의 텍스트를 가리키는 객체
3) 노드 객체의 특성
- 노드 객체가 공통으로 갖는 특성 : 이벤트에 관련된 기능은 EventTarget인터페이스가 제공, 트리 탐색 기능, 노드 정보 제공 기능 등은 Node 인터페이스가 제공한다.
- 노드 타입에 따라 고유한 기능 예시 : input 요소 노드 객체에는 value 프로퍼티가 필요하지만 div에서는 필요하지 않다.
39.2 요소 노드 취득
- Document.prototype.getElementById : 인수로 전달한 id어트리뷰트값 요소 노드를 탐색하여 단 하나의 요소 노드를 반환한다. 일치하는 노드가 없으면 null을 반환한다.
- Document.prototype.getElementsByTagName : 인수로 전달한 태그 이름의 모든 요소들을 탐색하여 반환한다. 여러 개의 요소 노드 객체를 갖는 DOMCollenction객체를 반환한다. DOMCollenction은 배열 객체이면서 이터러블이다.
- Docment.prototype.getElementsByClassName : 인수로 전달한 class의 어트리뷰트 값을 갖는 모든 요소 노드들을 탐색한다. 존재하지 않는 경우 빈 객체 DOMCollenction 을 반환한다.
- Docment.prototype.querySelectorAll : CSS 선택자를 이용한 요소 노드 취득으로 인수로 전달한 CSS 선택자를 만족시키는 모든 노들을 탐색한다. 존재하지 않으면 빈 NodeList 객체를 반환한다. 문법에 맞지 않은 경우 에러가 발생한다.
- Element.prototype.maches : 인수로 전달한 CSS 선택자를 통해 특정 요소 노드를 취득한다.
HTMLCollenction과 NodeList 과 NodeList
DOM API가 여러 개의 결과값을 반환하기 위한 DOM 컬렉션 객체로, 모두 유사 배열이면서 이터러블이다.
- HTMLCollenction: 언제나 live 객체이다.
- NodeCollection: 노드 객체의 상태 변화를 실시간으로 반영한다.
- NodeList : 실시간으로 노드 객체의 상태 변경을 반영하지 않는 객체이다.
39.3 노드 탐색
- Document.prototype.getElementById : 인수로 전달한 id어트리뷰트값 요소 노드를 탐색하여 단 하나의 요소 노드를 반환한다. 일치하는 노드가 없으면 null을 반환한다.
- Node.porotype.childNodes, Element.prototype.children : 자식 노드를 탐색한다.
- Node.porotype.hasChildNodes : 자식 노드가 존재하는지 확인한다. 불리언 값을 반환한다. 리프 노드라면 텍스트 노드를 포함한다.
- Node.prototype.parentNode : 부모 노드를 탐색한다.
- Node.prototype.previousSibling,Node.prototype.nextSibling : 형제 노드를 탐색한다.
39.4 노드 정보 취득
- Node.prototype.nodeType : 노드 객체의 종류(타입)을 나타내는 상수를 반환한다.
- Node.prototype.nodeName : 노드 이름을 문자열로 반환한다.
39.5 요소 노드의 텍스트 조작
- Node.prototype.nodeValue : 노드 객체의 값(텍스트)를 가져올 수 있고 (getter) , 설정할 수 있다 (setter)
- Node.prototype.textContent : 요소 노드의 텍스트와 모든 자손 노드의 텍스트를 취득하거나 변경한다. HTML 마크업은 무시된다. 이와 유사한 동작을 하는 innerText 프로퍼티가 있는데, 두가지 이유로 지양하는 것이 좋다. 1) innerText프로퍼티는 css에 순종적이라 visibility:hidden으로 지정된 요소 노드의 텍스트를 반환하지 않는다. 2) textContent보다 느리다.
39.6 DOM조작
새로운 노드를 생성하여 DOM에 추가하거나 기존 노드를 삭제 또는 교체한다.
- Element.prototype.innerHTML : 요소 노드의 콘텐츠 영역 내에 포함된 모든 HTML마크업을 문자열로 반환한다. 사용자로부터 입력받은 데이터를 그대로 innerHTML에 할당하는 것은 크로스 사이트 스크립팅 공격에 취약하므로 위험하다. 구현이 간단하고 직관적이지만 삽입될 위치를 지정할 수 없다는 단점이 있다.
- Element.prototype.insertAdjancentHTML : 기존 요소를 제거하지 않으면서 위치를 지정해 새로운 요소를 반환한다.
노드 생성과 추가
- element.prototype.createElemenmt(tagName) : 요소 노드를 생성한다.
- element.prototype.createTextNode(text) : 텍스트 노드를 생성한다.
- Node.prototype.appendChild(childNode) : 매개변수의 노드를 요소 노드의 마지막 자식 노드로 추가한다.
복수의 노드 생성과 추가
- 생성한 노드를 번번히 appendChild로 추가 할 경우 DOM을 여러 번 변경하게 된다. 이를 회피하기 위해 DocumentFragment노드를 사용할 수 있다. 노드 객체의 일종으로, 부모 노드가 없어서 기존DOM과는 별도로 존재하며, 서브 DOM을 구성하여 기존 DOM에 추가하기 위한 용도로 사용한다.
노드 삽입
- Node.prototype.appendChild : 매개변수의 노드를 요소 노드의 마지막 자식 노드로 추가한다. 요소를 DOM에 추가할 수도 있다. 위치 지정이 불가능하다.
- Node.prototype.insertBefore : 첫 번째 인수로 전달받은 노드를 두 번째 인수로 전달받은 노드 앞에 삽입한다.
노드 복사
- Node.prototype.cloneNode : 노드의 사본을 생성하여 반환한다. 매개변수 deep에 true를 전달하면 깊은 복사로 자식 노드까지 복사되고, false를 전달하거나 생략하면 얕은 복사로 자식 노드를 제외한 노드 자신만의 사본을 생성한다.
노드 교체
- Node.prototype.replaceChild : 자신을 호출한 노드의 자식 노드를 다른 노드로 교체한다.
노드 삭제
- Node.prototype.removeChild(child) : child 매개변수에 인수로 전달한 노드를 DOM에서 삭제한다.
39.7 어트리뷰트
- HTML요소는 여러 개의 어트리뷰트(속성)을 가질 수 있다.
- HTML 요소의 시작 태그에 어트리뷰트 이름="어트리뷰트 값" 형식으로 정의한다.
- 노드 요소의 모든 어트리뷰트 노드는 Element.prototype.attributes 프로퍼티로 취득한다.
- 어트리뷰트 조작은 Element.prototype.getAttribute/setAttribute 메서드를 사용할 수 있다.
- data 어트리뷰트(data- 접두사가 붙은 어트리뷰트)와 dataset 프로퍼티를 이용하면 HTML요소에 정의한 사용자 정의 어트리뷰트와 자바스크립트 간 데이터를 교환할 수 있다.
HTML 어트리뷰트와 DOM 프로퍼티
- HTML 어트리뷰트는 DOM에서 중복 관리되는 것처럼 보인다. 그러나 요소 노드는 상태를 가지고 있으며, 초기 상태와 최신 상태 2개를 관리한다.
- HTML어트리뷰트는 HTML요소의 초기 상태를 의미하며, 이는 변하지 않는다. HTML요소의 초기 상태는 어트리뷰트 노드에서 관리한다.
- DOM프로퍼티는 사용자가 입력한 최신 상태를 관리한다. DOM프로퍼티는 사용자의 입력에 의한 상태 변화에 반응하여 언제나 최신 상태를 유지한다.
- HTML어트리뷰트와 DOM 프로퍼티는 반드시 1:1로 대응하는 것은 아니다. ex. checkbox요소의 checked 어트리뷰트 값은 문자열이지만 프로퍼티 값은 불리언 타입이다.
39.8 스타일
- 인라인 스타일 : HTMLElement.prototype.style 프로퍼티를 이용하여 케밥케이스 스타일로 인라인 스타일을 추가/변경할 수 있다.
- CSS 클래스 : 클래스 선택자를 이용하여 Element.prototype.className을 변경하여 미리 작성한 CSS class에 연결한다.
- Element.prototype.classList 프로퍼티는 class 어트리뷰트의 정보를 잡은 DOMTokenList객체를 반환한다.
- DOMTokenList객체는 .add(...className) , remove(...className), item(index), contains(className), replace(old,new), toggle(className[,force]) 의 유용한 메서드를 지원한다.
'JavaScript' 카테고리의 다른 글
모던 자바스크립트 Deep Dive ― (9) (1) | 2022.11.08 |
---|---|
eslint --fix found some errors ( Error: unreachable ) (0) | 2022.10.31 |
모던 자바스크립트 Deep Dive ― (8) (1) | 2022.10.31 |
모던 자바스크립트 Deep Dive ― (7) (0) | 2022.10.28 |
모던 자바스크립트 Deep Dive ― (6) (0) | 2022.10.21 |