FrontEnd/JavaScript
Modern JavaScript Document Object Model
is..cy
2023. 3. 1. 18:37
1. DOM (Document Object Model)
- 텍스트 형식 웹문서를 브라우저에서 랜더링하기 위해 필요
- 모든 Element, Attribute, Text를 각 객체로 만들고 트리구조로 구성
- JavaScript를 통해 동적으로 변경
2. DOM API (Document Object Model Application Programming Interface)
- DOM에 접근하고 변경하는 프로퍼티와 메소드의 집합
- HTML 문서에 대한 모델 구성 : 브라우저는 Html 문서를 로드하고 문서 모델을 메모리에 DOM Tree 형태로 생성
- HTML 문서 내의 각 요소에 접근/수정
3. DOM Tree
- 문서 노드 (Document Node) : 트리 최상위에 존재하며 Element, Attribute, Text Node에 접근하려면 문서노드를 통해야함
- 요소 노드 (Element Node) : 중첩에 의한 부자관계
- 어트리뷰트 노드 (Attribute Node) : 특정 요소의 자식이 아닌 요소의 일부
- 텍스트 노드 (Text Node ) : 요소 노드의 자식이며 자식노드를 가질 수 없다. (DOM tree의 최종단)
4. Element 접근
- document.getElementById(id) : 요소노드 한개 선택
- document.querySelector(cssSelector) : 요소노드 선택, 복수 선택시 첫번째요소
- document.getElementsByClassName(class) : 여러 개의 요소 노드 선택 (유사배열형태)
//document.getElementsByClassName() 예시
const elems = document.getElementsByClassName('red');
// 클래스 어트리뷰트의 값을 변경
for (let i = 0; i < elems.length; i++) {
elems[i].className = 'blue';
}
5. Parent Node Traversing (부모노드탐색)
// 1. 부모노드
const elem = document.querySelector('#two');
elem.parentNode.className = 'blue';
// 2. 자식노드
// first Child
elem.firstChild.className = 'blue';
// last Child
elem.lastChild.className = 'blue';
// 3. 자식노드 존재여부
if (elem.hasChildNodes()) {
// 4. childNodes : 텍스트 요소 포함한 모든 자식요소 반환 (return NodeList)
console.log(elem.childNodes);
// NodeList(9) [text, li#one.red, text etc...]
// 5. children : 자식요소 중 Element type 요소만을 반환 (return HTMLCollection)
console.log(elem.children);
// HTMLCollection(4) [li#one.red, li#two.red, li#three.red etc...]
}
// 6. nextElementSibling, previousElementSibling : text node 포함 모든 형제노드
// 7. previousElementSibling, nextElementSibling : 형제노드 중에서 Element type 요소만 탐색
const elem = document.querySelector('ul');
elem.firstElementChild.nextElementSibling.className = 'blue';
elem.firstElementChild.nextElementSibling.previousElementSibling.className = 'blue';
6. DOM Manipulation
// 1. Node Info 얻기
// 해당 텍스트 노드의 부모 요소 노드를 선택
const one = document.getElementById('one');
console.dir(one); // HTMLLIElement: li#one.red
// 노드의 정보
console.log(one.nodeName); // LI
console.log(one.nodeType); // 1: Element node
// 노드의 값
console.log(textNode.nodeValue); // Seoul
// nodeValue 프로퍼티를 이용하여 텍스트를 수정
textNode.nodeValue = 'Pusan';
// 2. Class Info 변경
const elems = document.querySelectorAll('li');
// 2.1 className
// 이름이 여러개일시 split('')이용
[...elems].forEach(elem => {
if (elem.className === 'red') {
elem.className = 'blue'; // class 어트리뷰트 값 변경
}
});
// 2.2 classList
// add, remove, item, toggle, contains, replace 제공
[...elems].forEach(elem => {
if (elem.classList.contains('blue')) { // list에서 해당이름 포함시
elem.classList.replace('blue', 'red'); // class 어트리뷰트 값 변경
}
});
// 3. Attribute 조작
// 3.1 hasAttribute : Attribute 존재 확인
if (!input.hasAttribute('value')) {
// 3.2 setAttribute : Attribute 세팅
input.setAttribute('value', 'hello!');
}
// 3.3 getAttribute : 어트리뷰트 값을 취득
console.log(input.getAttribute('value')); // hello!
// 3.4 removeAttribute : value 어트리뷰트를 제거
input.removeAttribute('value');
7. HTML Manipulation
- Html도 조작이 가능하나 XSS : Cross-site Scripting Attacks 에 취약
// 1. textContent : 마크업이 무시된 요소의 텍스트 내용
// 요소의 텍스트 취득
console.log(one.textContent); // Seoul
// 요소의 텍스트 변경
one.textContent += ', Korea';
console.log(one.textContent); // Seoul, Korea
// 요소의 마크업이 포함된 콘텐츠 변경.
one.textContent = '<h1>Heading</h1>';
// 마크업이 문자열로 표시된다.
console.log(one.textContent); // <h1>Heading</h1>
// 2. innerHTML : 마크업 포함된 문자열
console.log(ul.innerHTML);
/*
<li id="one" class="red">Seoul</li>
*/
// 3. innerText : 요소 텍스트에만 접근, CSS에 영향을 많이 받고 textContent 프로퍼티보다 느려 사용권장x
8. DOM 조작방식
// 1. createElement : 태그이름을 인자로 전달하여 요소 생성
const newElem = document.createElement('li');
// 2. createTextNode : 텍스트 노드를 생성
const newText = document.createTextNode('Beijing');
// 3. appendChild : 텍스트 노드를 newElem 자식으로 DOM 트리에 추가
newElem.appendChild(newText);
// 4. appendChild : newElem을 container의 자식으로 DOM 트리에 추가. 마지막 요소로 추가
container.appendChild(newElem);
// 5. removeChild : container의 자식인 removeElem 요소를 DOM 트리에 제거
container.removeChild(removeElem);
// 6. insertAdjacentHTML : 마크업이 포함된 요소 추가 (XSS에 취약)
one.insertAdjacentHTML('beforeend', '<em class="blue">, Korea</em>');
9. Style Manipulation
// 1. 스타일 선언 : CamelCase로 변환하여 사용
four.style.fontSize = '2em';
// 2. window.getComputedStyle(elem, null).getPropertyValue(prop) : style property 얻음
// key, value 형태로 얻음
const border = getStyle(box, 'border');