DOM은 Document Object Model의 약자로, HTML(Document)에 접근하여 Object(JavaScript Object)처럼 HTML을 조작(Manipulation)할 수 있는 Model이라는 의미를 가지고 있습니다. 즉, 여러분이 자바스크립트를 사용하는 방법을 알고 있으면 DOM을 활용하여 HTML을 조작할 수 있다는 의미입니다.
우리가 HTML 을 이용해 어떤 페이지를 구축했다고 하자.
그 페이지에 만든 버튼은 우리가 원하는대로 작동할까? 당연히 그렇지 않다.
우리는 이 죽어있는 홈페이지에 생명을 불어넣기 위해 DOM 을 활용해야 한다.
다음의 간단한 질문을 통해 기본적인 HTML 상식을 확인해보자.
body 엘리먼트의 자식 엘리먼트는 총 몇 개인가?
id 이름이 news-contents 인 div 엘리먼트의 부모 엘리먼트는 무엇인가?
<html>
<body>
<div id="nav">
<div class="logo"></div>
<div class="menu-wrapper">
<div class="menu"></div>
<div class="menu"></div>
<div class="menu"></div>
<div class="profile-photo"></div>
</div>
</div>
<div id="news-contents">
<div class="news-content-wrapper">
<div class="news-picture"></div>
<div class="news-title"></div>
<div class="news-description"></div>
</div>
</div>
<div id="footer"></div>
</body>
</html>
충분히 고민했는가? 답은 아래와 같다.
<div id="nav">
<div id="news-contents">
<div id="footer">
<div id="news-contents>
의 부모는 body 이다. 위와 같이 매번 찾고자 하는 것을 직접 우리 눈으로 일일이 확인하는 것은 비효율적이다.
지금부터 간단한 코드를 사용하여 위 문제들을 좀 더 쉽게 접근할 수 있도록 해결해보자.
console.log(document.body)
를 통해 body 에 접근할 수 있지만 DOM 구조를 조회하기 위해서는
console.dir(document.body)
가 유용하다고 할 수 있다.
차이점이라면 console.log
와 다르게 console.dir
는 DOM을 객체의 모습으로 보여준다는 점이다.
body 엘리먼트의 자식 엘리먼트를 찾고 싶다면 document.body.children
을 사용하면 된다.
body의 자식 엘리먼트는 다음과 같다.
<div id="nav">
<div id="news-contents">
<div id="footer">
그렇다면, 저 자식들의 부모가 누군지 알 수 있는 방법도 있지 않을까?
만약, id 가 nav 인 엘리먼트의 부모를 찾고 싶다면 방법은 다음과 같다.
id 가 nav 인 엘리먼트를 지칭하는 값을 변수에 저장한다.
해당 변수에 .parentNode
를 붙힌다.
(부모인 body 를 가리키는 모습)
자식 엘리먼트도 위와 같은 방법으로 찾을 수 있다.
.childNodes
를 붙힌다.(nav 의 자식들을 배열의 리스트로 나열하는 모습)
위에서 알 수 있듯이 DOM 구조는 가족 관계도와 그 구조가 유사하다.
이렇게 나무의 나뭇가지가 뻗어나가는 듯한 구조를 TREE 구조라고 한다.
사진 출처 : 코드스테이츠
✔ TREE 구조의 가장 큰 특징은 부모가 하나이고, 부모가 자식을 여러개 가진다는 점이다.
(생물학적으로 따지면 당연한 사실)
document.createElement()
를 사용하면 된다.
()
안에는 원하는 태그명을 넣으면 된다.
💡 document.createElement('div') // <div></div> 생성
.append
를 사용하면 된다.
먼저, 만든 엘리먼트를 변수에 저장해두자.
💡 let div = document.createElement('div')
그리고 body 에 div 엘리먼트를 넣어보자.
💡 document.body.append(div)
(위 사진을 보면 body 에 div 태그가 추가된 것을 볼 수 있다)
document.querySelector()
를 사용하면 된다.
()
안에는 찾고자 하는 태그 이름을 입력하면 되는데 id 와 class 를 부르는 방식이 다르다.
id 태그를 조회할 때는 이름 앞에 # 을 붙힌다.
💡 (document.querySelector('#tweet')
class 태그를 조회할 때는 이름 앞에 . 을 붙힌다.
💡 (document.querySelector('.tweet')
하지만 querySelector 는 tweet 이란 클래스가 여러개 있다 하더라도 하나만 호출한다.
따라서 여러개를 가져오기 위해서는 document.querySelectorAll()
을 사용하면 된다.
id 태그를 조회할 때는 이름 앞에 # 을 붙힌다.
💡 (document.querySelectorAll('#tweet');
class 태그를 조회할 때는 이름 앞에 . 을 붙힌다.
💡 (document.querySelectorAll('.tweet');
div 태그를 하나 만들어서 변수에 해당 값을 할당해보자.
💡 let div = document.createElement('div'); // <div></div>
이제 저 태그 사이에 내용을 넣어줄 것이다.
.textContent
를 사용하면 문자열을 넣어줄 수 있다.
💡 div.textContent = 'Hello!'; // <div>Hello!</div>
이제 만들어진 div 태그에 qwer 이라는 class 를 지정해보자.
classList.add()
를 사용하면 해당 태그에 클래스를 추가해줄 수 있다.
💡 div.classList.add('qwer'); // <div class="qwer">Hello!</div>
태그를 삭제하려면 .remove()
를 사용하면 된다.
const container = document.querySelector('#container')
const tweetDiv = document.createElement('div') // <div></div>
container.append(tweetDiv) // 부모인 container 에 tweetDiv 를 넣는다.
tweetDiv.remove() // 이렇게 append 했던 엘리먼트를 삭제할 수 있다.
만약, 자식만 지우고 싶다면 .removeChild()
를 사용하면 된다.
const container = document.querySelector('#container');
while (container.children.length > 1) {
container.removeChild(container.lastChild);
} // 자식을 하나만 남겨두고 모두 제거한다.
위와 같이 while 문을 사용해 원하는 자식을 제거할 수도 있다.