JS Day 15 DOM API
10 Mar 2021 | JavascriptJS Day 15 DOM API
-
DOM API
- DOM(Document Object Model) : 문서 객체 모델, 웹 페이지 내의 모든 콘텐츠를 객체로 나타내어 준다
- DOM에 접근하기 위해 document 객체를 이용한다
document.body.style.background = 'red';
-
https://dom.spec.whatwg.org/ (DOM 관련 문서)
-
DOM에서는 모든 HTML 태그, 태그 내의 텍스트는 객체이다
-
태그 하나가 감싸고 있는 자식 태그를 중첩 태그(nested teg)라 한다
-
이런 모든 객체는 자바스크립트로 조작할 수 있다
-
태그 하나 하나를 node라 하며 node는 트리 구조로 구성된다
-
node types
- DOM의 진입점이 되는 document node
- DOM 트리를 구성하는 HTML 태그인 element node
- 텍스트를 포함하는 text node
- 주석을 담는 comment node
-
DOM 탐색하기
- 브라우저가 script를 읽는 도중 DOM 요소에 접근하면 null 예외가 나올 수 있으니 주의
- childNodes 컬렉션은 text node를 포함한 모든 자식 노드를 담고 있다
- HTML 태그만 선택하고 싶으면
children
을 써야한다 - childNodes는 유사 배열인 iterable 객체로 array API (forEach,filter,map,reduce 등)를 사용할 수 없다
- for .. of를 사용해 순회하거나 배열에 담아서 array API를 사용해 순회한다
- firstChild는 첫 번째, lastChild는 마지막 자식 노드에 접근 할 수 있다
- DOM 컬렉션은 read-only의 속성을 가진다
childNodes[i] = newValue; // 자식 노드를 교체하는 것이 불가능하다
- for .. in 은 원치 않는 프로퍼티까지 순회 대상에 포함되므로 사용 x
- 형제 노드는 nextSibling, previousSibling / 부모 노드는 parentNode로 접근할 수 있다
- HTML 태그만 찾고 싶다면
parentElement
,previous/nextElementSibling
을 사용한다
-
DOM 검색하기
- querySelector(‘.class / #id / tag’)
- querySelectorAll(‘:hover’) : NodeList 반환
- CSS 가상 클래스인 :hover, :active 등도 검색할 수 있다
- getElementById(‘id’)
- getElementsByTagName / ClassName / Name : HTML 컬렉션 반환
- NodeList는 forEach가 먹힌다 / HTML 컬렉션은 안먹는다
-
DOM 조작하기
- innerHTML 강력하지만 XSS 공격에 취약하여 사용이 자제된다
- innerText : 사용자에게 보여지는 텍스트를 가져오거나 수정 가능
- textContent : 텍스트를 가져오거나 수정 가능, XSS 공격의 위험이 없다
- innerText와 textContent의 차이 : textContent는 해당 노드가 가지고 있는 텍스트를 가져온다. display: none 등 숨겨진 텍스트도 가져온다
- HTML 태그에 data-xxxx=”value”를 설정하고 스크립트에서 dataset으로 이 값에 접근하고 수정할 수 있다
- 이를 용용해 CSS를 활용하여 많은 것을 할 수 있다
<span id="user" data-name="show">안녕</span> <script> user.dataset.name = 'hide'; </script> <style> span[data-name='hide'] { display: none; } </style>
node.append(노드나 문자열)
– 노드나 문자열을node
끝에 삽입node.prepend(노드나 문자열)
– 노드나 문자열을node
맨 앞에 삽입node.before(노드나 문자열)
–- 노드나 문자열을node
이전에 삽입node.after(노드나 문자열)
–- 노드나 문자열을node
다음에 삽입node.replaceWith(노드나 문자열)
–-node
를 새로운 노드나 문자열로 대체node.remove()
– 노드를 삭제node.cloneNode(true/false)
– true는 노드의 자손까지 복제, false는 해당 노드만 복제- DocumentFragment에 여러 노드를 담아서 한방에 삽입할 수도 있다
- 삽입하면 DocumentFragment는 사라지고 가지고 있던 요소들만 삽입된다
let fragment = new DocumentFragment(); for(let i=0; i<3; i++) { let li = document.createElement('li'); li.append(i); fragment.append(li); } ul.append(fragment);
- node.className은 해당 클래스 이름을 가져온다
elem.classList.add/remove("class")
–class
를 추가하거나 제거elem.classList.toggle("class")
–class
가 존재할 경우class
를 제거하고, 그렇지 않은 경우엔 추가elem.classList.contains("class")
–class
존재 여부에 따라true/false
를 반환- classList는 iterable 객체이므로 for…of로 순회가 가능하다
- className으로 class를 바꾸면 덮어써버리는 반면 classList.add는 추가하는 개념이다