모던 자바스크립트 Deep Dive 글 목록(스터디)
https://hello-kk.tistory.com/780
★DOM 조작에 의해 리플로우, 리페인트 발생 (성능 최적화 고려)★
innerHTML (setter/getter) | (1) 모든 자식노드를 삭제한 후 (2) 새롭게 노드를 생성하여 (3) 자식 요소로 추가 |
삽입 위치 지정 불가 |
insertAdjacentHTML(위치,HTML문자열) | 기존 요소 유지 | 위치 지정해서 요소 삽입 |
=> 둘다, XSS(크로스 사이트 스크립팅 공격)에 취약 =>마크업 파싱하기 때문
doxument.getElementById() | document.createElement('li') | document.createTextNode() | $li.appendChild() |
노드를 생성하면, 독립적으로 존재하는 상태이기 때문에 기존 DOM에 추가하는 과정이 필요하다
노드를 추가하는 방법
(1) 요소 노드에 자식 노드가 있는 경우
(2) 요소 노드에 자식 노드가 없는 경우
기존 DOM에 추가될 때 DOM이 변경되기 때문에 리플로우와 리페인트가 실행된다.
따라서, for문을 통해 요소를 기존 DOM에 n번 추가하는 경우 n번의 리플로우 리페인트가 실행
컨테이너 요소 활용: 기촌 DOM에 한번만 자식 노드들을 모두 추가하기 위해
div 컨테이너 노드 | document.createElement('div') | 불필요한 컨테이너 요소 div가 DOM에 추가됨 |
DocumentFragment 컨테이너 노드 | document.createDocumentFragment(); | DOM에 컨테이너가 추가될 때, 컨테이너인 자신은 제거되고, 자신의 자식 노드만 DOM에 추가된다. |
왜 노드를 자식의 자식 노드, 자식노드, DOM에 추가 하는 순서로 하는걸까? 생각했는데, 리렌더링이 일어나는 조건을 적게 일어나게 하기 위한게 아닐까(리플로우와 리페인트)
Node(부모의 부모노드)
노드 삽입 | Node.prototype.insertBefore(nowNode, childNode) | 첫번째 인수(자식 노드가 됨) 두번째 인수(부모 노드가 됨) *두번째 인수 노드의 마지막 자식 요소 앞에 삽입 |
노드 이동 | Node.prototype.insertBefore(nowNode, childNode) | 이미 노드가 존재한다면 ( const [ $first, $second, ] = $parentNode.children ) 첫번째 인수의 노드를 제거하고, 두번째 인수 자식 노드 위치에 노드를 추가한다. |
노드 복사 | Node.prototype.cloneNode([deep: true | false]) | true: 노드를 깊은 복사(모든 자손 노드 포함한 사본) false: 노드를 얕은 복사(자신만의 사본. 자손 노드 불포함) |
노드 교체 | Node.prototype.replaceChild(newChild, oldChild) | 호출한 노드의 자식 노드를 교체 old노드는 DOM에서 제거 |
노드 삭제 | Node.prototype.removeChild(child) | 매개변수로 전달한 노드를 DOM에서 삭제 |
어트리뷰트 노드는 attributes 프로퍼티로 얻을 수 있다(NamedNodeMap 객체를 반환)
const { attributes } = document.getElementById('user')
attributes.id.value
attributes.type.value
attributes.value.value
attributes 프로퍼티 | getter로 값 취득만 가능 어트리뷰트 값을 참조 할 때 사용 |
Element.prototype.getAttribute(attributeName) | attributes 프로퍼티를 통하지 않는다 직접 HTML 어트리뷰트 값을 취득 '문자열'로 입력 |
Element.prototype.setAttribute(attributeName, attributeValue) | attributes 프로퍼티를 통하지 않는다 직접 HTML 어트리뷰트 값을 변경 '문자열'로 입력 초기 상태값을 변경 |
Element.prototype.hasAttribute(attributeName) | HTML 어트리뷰트 존재 여부 확인 '문자열'로 입력 |
Element.prototype.removeAttribute(attributeName) | 특정 HTML 어트리뷰트 삭제 '문자열'로 입력 |
● HTML 어트리뷰트에 대응하는 DOM 프로퍼티가 존재. 왜 각각 존재하는 걸까? => 요소노드는 상태(state)를 갖고있다!
HTML 어트리뷰트 | HTML 요소의 초기 상태 지정 불변 초기 상태를 갖는 이유: 처음 표시하는 경우 또는 새로고침 어트리뷰트 노드에서 관리 |
DOM 프로퍼티 | 최신 상태 관리: HTML 어트리뷰트에 대응하는 요소 노드의 DOM 프로퍼티가 관리 사용자 입력에 의한 상태변화 |
결국 같은 의미 → 00 어트리뷰트, 00 프로퍼티
data 어트리뷰트와 dataset 프로퍼티
HTMLElement.prototype.style 프로퍼티 (setter/getter)
classList
add | remove | item | contains | replace | toggle |
요소에 적용되어있는 CSS 스타일 참조
의사 요소를 지정하는 문자열 전달 가능
DOM 표준: WHATWG
39.6 DOM 조작
새로운 노드를 생성하여 DOM에 추가, 기존 노드를 삭제 또는 교체
39.6.1 innerHTML
● (getter) 마크업이 포함된 문자열을 문자열 그대로 (변환없이) 반환
● (setter) 요소 노드의 innerHTML 프로퍼티에 문자열을 할당하면 마크업이 파싱되어, 요소 노드의 자식 노드로 DOM에 반환
● DOMPurify 라이브러리 권장
DOMPurify.sanitize('<img ... >')
● 삽입 위치 지정 불가
39.6.2 insertAdjacentHTML 메서드
39.7 어트리뷰트
39.7.1 어트리뷰트 노드와 attributes 프로퍼티
HTML 어트리뷰트 당 하나의 어트리뷰트 노드가 생성
<input id='user' type='text' value='hello'>
=> 3개의 어트리뷰트 노드가 생성
39.7.2 HTML 어트리뷰트 조작
39.7.3 HTML 어트리뷰트 vs DOM 프로퍼티
HTML 어트리뷰트에 대응하는 DOM 프로퍼티
DOM 프로퍼티는 참조와 변경이 가능
39.7.4 data 어트리뷰트와 dataset 프로퍼티
39.8 스타일
인라인 스타일 조작
HTMLElement.prototype.style 프로퍼티 (setter/getter)
39.8.2 클래스 조작
Element.prototype.className (setter/getter)
Element.prototype.classList: class 어트리뷰트의 정보를 담은 객체 반환
39.8.3 요소에 적용되어있는 CSS 스타일 참조
의사 요소를 지정하는 문자열 전달 가능
getComputedStyle( $class, ':before' );
'Front-End > JavaScript' 카테고리의 다른 글
35장 스프레드 문법 36장 디스트럭처링 할당 (모던 자바스크립트 Deep Dive) (0) | 2023.06.05 |
---|---|
40장 이벤트 (모던 자바스크립트 Deep Dive) (0) | 2023.05.28 |
39장 DOM(~39.5.2) (모던 자바스크립트 Deep Dive) (0) | 2023.05.22 |
38장 브라우저 렌더링 과정/33장 Symbol/48장 모듈 (모던 자바스크립트 Deep Dive) (0) | 2023.05.18 |
37장 Set과 Map (모던 자바스크립트 Deep Dive) (1) | 2023.05.15 |