[JavaScript] DOM

정호·2023년 3월 6일
1

JavaScript

목록 보기
6/12

DOM이란

DOM은 HTML 문서의 계층적 구조와 정보를 표현하며 이를 제어할 수 있는 API, 즉 프로퍼티와 메서드를 제공하는 트리 자료구조

❖ API: Application Programming Interface의 약자로, 프로그램이 동작하는 환경을 제어하기 위해서 환경에서 제공되는 조작 장치입니다. 이 조작 장치는 프로그래밍 언어를 통해서 조작할 수 있습니다.

HTML 요소는 HTML문서를 구성하는 개별적인 요소를 뜻하며 렌더링 엔진에 의해 파싱되어 DOM을 구성하는 요소 노드 객체로 변환된다.
ex) 어트리뷰트 --> 어트리뷰트 노드, 텍스트콘텐츠 --> 텍스트노드

트리구조: 부모자식 노드로 구성되어있는 비선형 자료형 구조

  • 루트 노드: 부모가 존재하지않는 최상위 노드, 0개이상의 자식노드를 가짐
  • 리프 노드: 자식 노드가 없는 노드
    - 비선형 자료구조: 하나의 자료 뒤에 여러 개의 자료가 존재할 수 있는 구조

노드 객체들로 구성된 트리 자료구조를 DOM이라 하고 DOM트리라고 부른다.


39-01 예제 파싱

문서노드: document 루트 노드로써 document객체는 브라우저가 렌더링한 HTML문서 전체를 가리킨다.(전역객체 window) 따라서 window.document, document로 참조할 수 있다. 루트 노드이기 때문에 DOM트리의 노드들에 접근하기 위한 진입점 역할을 한다.

요소노드: html,head,body... HTML요소 간 중첩에 의해 부자 관계를 가지며 문서의 구조를 표현한다.

어트리뷰트노드: href="style.css,src="app.js" 어트리뷰트 노드는 ㅈ지정된 HTML 요소의 요소노드와 연결되어 있다. 어트리뷰트 노드에 접근하려면 먼저 요소 노드에 접근해야 한다.

텍스트노드: "Apple", "Banana" 텍스트 노드는 문서의 정보를 표현한다. 요소 노도의 자식이며, 리프 노드이다(DOM의 최종단). 텍스트 노드에 접근하려면 요소 노드에 접근해야 한다.


노드 객체의 상속구조

노드 객체는 자바스크립트 객체이므로 프로토타입에 의한 상속구조를 갖는다.
그림(39.1.3)
모든 노드객체는 Object, EventTarget, Node인터페이스를 상속받고 이 후에 문서 노드는 Document, 어트리뷰트 노드는 Attr인터페이스를 각각 상속받는다.

예제39.2

console.dir($input)



input요소 노드 객체도 다양한 특성을 갖는 객체이며, 상속을 통해 기능들을 제공받음
_-> input요소 노드 객체의 특성은 이벤트를 발생시키는 객체이면서 ,,, 트리 자료구조의 노드객체이면서 ,,,,, 등을 포함하는 하위 상위 객체

Properties에서 확인가능

공통된 기능일 수록 프로토타입 체인의 상위, 개별적 고유 기능일수록 프로토타입 체인 하위에 체인을 구축하여 상속구조를 갖는다.


요소 노드 취득 (공통)

  • id를 이용
  • html문서 내에서 유일한 값이여야한다.
  • 중복된 값이라면 가장 첫번재 요소 노드만 반환한다.
  • 존재하지 않을 경우 null을 반환한다.
  • 암묵적으로 id와 동일한 이름의 전역변수가 선언되어 노드 객체가 할당된다.
  • id값과 동일한 이름의 전역변수가 이미 선언되어 있다면 이 전역 변수에 노드 객체가 재할당되지 않는다.

태그 이름 이용한 요소 노드 취득

 const $elems = document.getElementsByTagName('li');

태그 이름이 li인 요소 노드를 모두 탐색하여 반환
탐색된 요소 노드들은 HTMLCollection 객체에 담겨 반환

// 모든 요소 노드를 탐색하여 반환한다.
const $all = document.getElementsByTagName('*');
// -> HTMLCollection(8) [html, head, body, ul, li#apple, li#banana, li#orange, script, apple: li#apple, banana: li#banana, orange: li#orange]

모든 요소 취득 메서드 인수를 *로 전달

const $fruits = document.getElementById('fruits');
const $lisFromFruits = $fruits.getElementsByTagName('li');

자손 노드 중에서 태그 이름이 li인 요소 노드를 탐색하는법

class 이름 이용한 요소 노드 취득

// class 값이 'fruit'인 요소 노드를 모두 탐색하여 HTMLCollection 객체에 담아 반환한다.
 const $elems = document.getElementsByClassName('fruit');
// 취득한 모든 요소의 CSS color 프로퍼티 값을 변경한다.
[...$elems].forEach(elem => { elem.style.color = 'red'; });

css 이름 이용한 요소 노드 취득

// class 어트리뷰트 값이 'banana'인 첫 번째 요소 노드를 탐색하여 반환한다.
const $elem = document.querySelector('.banana');

querySelector사용하면 하나만 선택

  // ul 요소의 자식 요소인 li 요소를 모두 탐색하여 반환한다.
const $elems = document.querySelectorAll('ul > li');

querySelectorAll 사용하여 여러개(li요소 모두) 선택가능

모든 요소를 선택하려면 querySelectorAll 인수를 *

특정 요소 취득

// $apple 노드는 '#fruits > li.apple'로 취득할 수 있다.
console.log($apple.matches('#fruits > li.apple'));  // true

.matches 조건에 부합하는지 여부확인


이터러블이란

순회 가능한 데이터 컬렉션을 이터레이션 프로토콜을 준수하는 이터러블로 통일하여 for..of, 스프레드, 배열 디스트럭처링 할당 대상으로 사용할 수 있게 함, 이터러블 프로토콜을 준수한 객체를 이터러블이라 한다.

즉 이터러블은 Symbol.iterator를 프로퍼티 키로 사용한 메서드를 직접 구현하거나 프로토타입 체인을 통해 상속받은 객체를 말한다.


HTMLCollection과 NodeList

HTMLCollection

getElementsByTagName,getElementsByClassName메서드가 반환하는 HTMLCollection 객체는 노드 객체의 상태변화를 실시간으로 반영하는 라이브 객체

NodeList

HTMLCollection 썼을때의 부작용을 해결하기 위해 사용 NodeList객체는 실시간으로 상태 변경을 반영하지 않는 객체

querySelectorAll메서드는 NodeList객체를 반환

childNodes는 실시간으로 반영하기 때문에 안전하게 사용하려면 객체를 배열로 변환하여 사용하는것이 좋다.


노드 탐색

요소 노드를 취득한 후, DOM트리를 옮겨 다니며 노드를 탐색해야할때 사용 노드 탐색 프로퍼티는 읽기 전용 접근자 프로퍼티 이다.

프로토타입: 어떤 객체의 상위(부모) 객체의 역할을 하는 객체, 하위 객체에게 자신의 프로퍼티와 메서드를 상속
프로토타입 체인: 프로토타입이 단방향 링크드 리스트 형태로 연결되어 있는 상속구조 해당 객체에 접근하려면 차례대로 검색
접근자 프로퍼티: 자체적으로 값을 갖지 않고 다른 데이터를 읽어올 때 사용하는 접근자 함수 프로퍼티


DOM 조작

새로운 노드를 생성하여 DOM에 추가하거나 기존 노드를 삭제, 교체하는 것
-리플로우, 리페인트발생

HTMl 마크업 문자열을 파싱하는 방법

innerHTML

  • Element.prototype.innerHTML프로퍼티는 HTML마크업을 취득,변경 요소 노드 내의 포함된 HTML마크업을 문자열로 변환한다.(마크업을 포함해 그대로반환)
document.getElementBYId('foo').innerHTML //Hello <span>world!</span>

요소 노드의 자식 노드로 DOM에 반영되어 마크업 문자열로 DOM조작이 가능하다.

단점

  • 직관적이고 간단하지만 크로스 사이트 스크립팅 공격에 취약 (공통된 단점)
  • 요소 노드의 모든 자식 노드를 제거하고 마크업 문자열을 파싱하여 자식 요소로 추가함
  • 새로운 요소를 추가할 때 위치 지정이 불가함

insertAdjacentHTML 메서드

기존 요소를 제거하지 않고 위치를 지정해 새로운 요소를 삽입할 수 있다.

직접 생성/삽입하는 메서드

1️⃣ 새로운 요소 노드 생성

const $li = document.createElement('li');

태그 이름을 나타내는 문자열(li)을 인수로 전달
2️⃣ 텍스트 노드 생성

const textNode = document.createTextNode('Banana');

3️⃣ 텍스트 노드를 요소 노드의 자식 노드로 추가

$li.appendChild(textNode);

4️⃣ 요소 노드를 DOM에 추가

$fruits.appendChild($li);

노드삽입

`Node.prototype.appendchild는 자신을 호출한 노드의 마지막 자식 노드로 DOM에 추가

document.getElementById('fruits').appendChild($li);
profile
열심히 기록할 예정🙃

0개의 댓글