DOM(Document Object Model)은 웹 페이지에 대한 인터페이스이다. 뷰 포트에 무엇을 렌더링 할지 결정하거나, CSS나 HTML의 구조, 스타일 등이 자바스크립트 프로그램에 의해 수정될 때 사용한다.
위와 같은 형태를 DOM의 트리구조라고 한다. HTML의 트리구조와 상당히 닮아있는 모습을 확인할 수 있다.
<script>
태그를 이용하여 불러온다. script 요소는 등장과 함께 실행된다. DOM 트리가 생성되기 전에 자바스크립트가 생성되지도 않은 DOM을 조작할 수 있기 때문에 가능한<body>
태그의 가장 아래에서 불러와야 한다.
JavaScript와 DOM이 비슷한 개념으로 인식될 수 있다. 하지만 DOM은 항상 유효한 HTML 형식이며, 자바스크립트에 수정될 수 있는 동적 모델이어야 한다. 문서의 내용을 보여주는 인터페이스 역할과 동시에 수정의 역할도 가능해야 한다는 뜻이다. 또 DOM은 브라우저에서 보여지는 내용이 아니기 때문에
display: none
과 같이 보이지 않는 요소도 포함된다.
Yes !! 😀 아래의 코드를 수정해보자.
<body> <div id="container"> <h2>Tweet List</h2> <div class="tweet">rabbit</div> <div class="tweet">horse</div> <div class="tweet">fox</div> <div class="tweet">hippo</div> </div> </body>
먼저 div 요소를 추가해보자.
const tweetDiv = document.createElement('div')
html로 작성한 요소를 읽어보자.
const oneTweet = document.querySelector('tweet')
이러면 class 'tweet'에 해당하는 요소 중 첫 번째 요소가 불려온다. tweet에 해당하는 모든 요소를 불러오고 싶다면 어떻게 할까?
const allTweet = document.querySelectorAll('tweet')
이러면 allTweet에 class tweet에 해당하는 요소들이 유사 배열(Array-like Object)로 담긴다.
요소들의 값을 추가하거나 수정하고 싶다면 어떻게 해야 좋을까? 먼저 텍스트를 추가해보자.
tweetDiv.textContent = "crocodile";
tweetDiv에 다른 tweet요소들과 같은 스타일을 적용하고 싶다면 tweetDiv에 class를 추가해주면 된다.
tweetDiv.classList.add('tweet');
이 외에도 setAttribute 메소드를 이용해 속성 값을 수정할 수 있다.
tweetDiv.setAttribute('class', 'tweet');
이제 우리가 만든 tweetDiv를 삭제해보자.
tweetDiv.remove();
여러 개의 자식 엘리먼트를 삭제하고 싶다면 어떻게 할까?
document.querySelector('#container').innerHTML = ""; // id가 container인 엘리먼트 아래의 모든 엘리먼트 지움
이런 식으로 속을 아예 비워버리는 방법이 있다. 아래처럼 반복문으로 아예 삭제하는 방법도 있다.
while (container.firstChild) { container.removeChild(container.firstChild); // 모든 자식 요소를 삭제.
또 클래스 이름에 해당하는 요소를 직접 찾아 삭제하는 방법도 있다.
tweets.forEach(function(tweet) { tweet.remove(); })
tweetDiv를 삭제가 아닌, 실제 html에 추가하고 싶다면 어떻게 할까?
const container = document.querySelector('#container') container.append(tweetDiv)
이러면 tweetDiv를 container의 마지막 자식 요소로 추가할 수 있다!
innerHTML은 'Element'의 속성으로, 해당 요소의 HTML 전체 내용을 가져온다. textContent는 'Node'의 속성으로, 태그와 상관없이 해당 노드가 가지고 있는 텍스트 값을 그대로 읽는다.
createDocumentFragment
는 임시 저장용 특수 노드이다. 메인 트리구조와 연결되어 있지 않다. 이것의 parentNode 는 null 이지만, append와 같은 메소드로 구조를 늘릴 수는 있다.
<template>
태그는 추가되거나 복사될 수 있는 HTML 요소들을 정의할 때 사용한다. 이는 처음에 보이지 않지만, 사용자가 원할 때 복제하여 보이도록 렌더링된다.
복사가 안된다 !! 띠용 ~~ 기존 엘리먼트를 새로운 위치로 이동시킨다. 한 부모에 같은 자식 필요 없다.
element.offsetTop
으로 부모 요소로부터의 top좌표를 조회할 수 있다.
element.offsetWidth
,element.offsetHeigth
메소드로 요소의 가로 세로 길이를pixel
단위로 조회할 수 있다.
HTML
은node
의 집합이다.node
에는 여러 종류가 있는데,element
가 그 중 하나이다. 아래 사진은node
의 종류들이다.
element
는 특별히<tag>
로 갇혀있는 노드를 일컫는다. 때문에 텍스트와 같은 다른 노드들은 포함되지 않는다.
childNodes
는 자식 노드에 접근한다.children
은 자식 요소에 접근한다. 위에서 설명했듯이, node 와 element는 다르기 때문에children
은 비요소 노드에 접근하지 않는다.
remove
는 노드를 삭제하고 바로 종료된다. 하지만removeChild
는 노드를 삭제하는 것이 아니라 DOM 트리에서 노드를 떼어내고 떨어진 참조(주소)를 반환한다. 이 참조를 변수에 저장하지 않으면 자바스크립트 엔진에 의해 잠시 후 삭제된다. 참조를 변수에 저장했다면 다른 곳에 갖다 붙이는 것도 가능하다.
var tweets = document.querySelectorAll('.tweet'); // 유사 배열 var tweet_array = Array.prototype.slice.call(tweets); // 배열로 바꿈