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');