돔... 그것은... 프론트엔드 개발자가 되고싶다면 꼭 알아야할 요소...
돔에서 가장 유명하고 잘 쓰이는 것은 이벤트이지만 그것만이 중요한 것은 아니다....
DOM(Document Object Model - 문서 객체 모델)
DOM은 쉽게 말하면 HTML과 자바스크립트를 연결해주는 다리같은 매개체입니다.
자세히 말하면, HTML 요소를 Object(JavaScript Object)처럼 조작(Manipulation)할 수 있는 Model입니다.
Window 객체의 document 프로퍼티를 통해 사용할 수 있습니다.
DOM은 프로그래머 관점에서 바라본 HTML입니다. DOM을 활용하면 브라우저 환경에서 자바스크립트를 이용해 HTML을 조작하고 단순한 문서에서 웹 앱으로 업그레이드 할 수 있습니다.
HTML의 구조는 자바스크립트 객체의 구조와 같이 트리 구조로 되어있습니다.
HTML 요소에 접근하고 조작하기 위해서는 해당 요소를 선택해야 합니다.
자바스크립트에서 해당 HTML 요소에 접근하는 방법은 다음과 같습니다.
- HTML 태그 이름(tag name)을 이용한 선택
- 아이디(id)를 이용한 선택
- 클래스(class)를 이용한 선택
- name 속성(attribute)을 이용한 선택
- CSS 선택자(selector)를 이용한 선택
- HTML 객체 집합(object collection)을 이용한 선택
javaScript로 DOM을 사용해서 HTML 조작하기
DOM을 javascript로 조작하기 위해서는, document 객체를 통해 HTML 엘리먼트를 생성(create)하고, 조회(read)하고, 갱신(update)하고, 삭제(delete)하고, 적용(append)할 줄 알아야 합니다.
- document.querySelector --- 조회하는 메소드. element를 CSS 방식으로 검색할 수 있습니다. 첫번째 것만 가져옵니다.
- document.cloneNode --- 복제하는 메소드
- document.importNode --- template을 활용하여 내용을 붙여넣을 때 사용하는 메소드
- document.querySelector('div') --- 최상단 div 하나만 조회
- document.getElementById('div') --- id가 div인 element 한개 조회 === document.querySelector('#div')
- document.getElementsByClassName('div') --- class가 div인 element 여러개 조회. 배열로 출력
- document.getElementsByTagName('div') --- div 전부 조회하는 방법 1. 배열로 출력
- document.querySelectorAll('div') --- div 전부 조회하는 방법 2. 배열로 출력
<script> 요소는 등장과 함께 실행된다는 사실을 꼭 기억합시다!!
DOM 구조를 조회할 때에는 console.dir이 유용합니다.
console.dir은 DOM을 객체의 모습으로 출력합니다.
console.dir(document.body) << 이런식으로 써서 body 찾아보기
- document.body.children --- 바로 body안의 자식 엘리먼트 찾기
- console.dir(document.body.children[1]) --- body의 첫번째 자식 찾기
매번 찾아가는것은 번거롭기때문에 변수를 선언해서 정보를 저장해두면 주소를 참조해서 더 편합니다.
let newsContents = document.body.children[1]
newsContents의 부모 엘리먼트를 가리키는 속성을 찾으려면, parentElement를 사용할 수 있습니다.
console.dir(document.body.children[1].parentElement) // body
console.dir(newsContents.parentElement) // body <- 선언을 해준 후 사용
DOM으로 HTML Element 추가 삭제 변경하기
- const newDiv = document.createElement('div') --- element 추가하기. 새로운 div element 만들기. 변수 선언해서 담기
- hiElement.setAttribute('id', 'javascript') --- Element를 추가하고 나서 class, id가 지정하고 싶을때
- hiElement.textContent = 'hi' --- textContent를 사용해서 안에 텍스트 추가
- document.body.append(newDiv) --- body에 넣기 위해서 append 메소드 사용하기
자바스크립트에서 원시 자료형인 변수의 값을 조회하기 위해서는, 변수의 이름으로 직접 조회할 수 있습니다. 그러나 DOM은 조금 특별한 방법을 사용해야 합니다. DOM으로 HTML 엘리먼트의 정보를 조회하기 위해서는 querySelector의 첫번째 인자로 셀렉터를 전달하여 확인할 수 있습니다.
querySelector는 셀렉터를 조회한다는 의미입니다. query의 의미가 "질문하다"라는 것을 알고 있다면 역할을 쉽게 유추하실 수 있습니다. 이 query라는 단어는 개발자 간에 "~를 조회한다"라는 의미를 "쿼리를 날리다"라는 jagon(특정 영역에서만 사용되는 단어)로 굳어졌기 때문에 알고 있어야 합니다.
- const one = document.querySelector('.new') --- new 클래스의 엘리먼트 중 첫번째 엘리먼트를 가져오는 것
- const new = document.querySelectorAll('.new') --- new 클래스의 모든 엘리먼트 가져오는 것
이렇게 조회한 HTML 엘리먼트들은 배열처럼 for문을 사용할 수 있습니다. 앞서 조회한 HTML 엘리먼트들은 배열이 아닙니다. 이런 '배열 아닌 배열'을 유사 배열, 배열형 객체 등 다양한 이름으로 부릅니다. 정식 명칭은 Array-like Object 입니다. Array-like Object 같이 개념을 설명하는 용어는 영어로도 명확하게 기억해두는 게 좋습니다.
- container.append(newDiv) -- 생성한 newDiv를 container의 맨 마지막 자식 엘리먼트로 적용
- newDiv.classList.add('tweet') --- CSS스타일링이 적용될 수 있도록 div 엘리먼트에 class를 추가
- newDiv.remove() --- 엘리먼트를 삭제
혹시 첫번째 자식만 지우고 싶다면, 아래의 코드를 참고하세요.
while ( container.firstChild) {
container.removeChild(container.firstChild);
}
// container의 첫번째 자식 엘리먼트가 있다면, 첫번째 자식 엘리먼트를 지워라
// 이렇게 하면 원하는 것까지만 지우기 어려울 수 있으니
//반복문을 써서 지우거나 클래스 이름명을 갖고있는 엘리먼트만 찾아서 지울 수 있음
// 1. 반복문 사용하기
while(container.children.length>1){
container.removeChild(container.lastChild);
}
// 2-1. 클래스 이름으로 지우기
tweets.forEach(function(tweet){
tweet.remove();
})
// 2-2. 클래스 이름으로 지우기
tweets.forEach(function(tweet){
for (let tweet of tweets){
tweet.remove()
}
Node는 Element의 상위 개념입니다. DOM 관련 객체는 대부분 Node 에서 파생되었다고 봐도 과언이 아닙니다. Node의 기능을 적용(Implements)한 객체는 여러 타입이 있는데, 그 중 가장 많이 사용되는 타입이 Element입니다.
DOM은 document 객체를 통해 HTML(root document)에 접근합니다.
BOM(Browser Object Model)이 window 객체를 통해 브라우져에 접근합니다.
'DOM > 기초' 카테고리의 다른 글
같은 엘리먼트를 appendChild 하면, 기존 엘리먼트를 복사할까? (0) | 2021.06.29 |
---|---|
DOM - 차이점 비교 (0) | 2021.06.29 |
createDocumentFragment (0) | 2021.06.29 |
DOM과 자바스크립트 (0) | 2021.06.29 |
이벤트 (Events) (0) | 2021.06.16 |