📢 어렵고 정석적인 개념 설명보다는 저같은 초보자도 이해하기 쉽게 정리하는 것을 원칙으로 포스팅하고 있습니다. 😄

[JavaScript] 자바스크립트 DOM 객체 조작하기 (CRUD)

DOM 추가/삭제하기

// 1. div라는 태그를 만든다.
const wrapDiv = document.createElement('div');

// 2. 만든 div에 text를 넣는다. (2가지 방법)
wrapDiv.textContent = 'Hello World!';
wrapDiv.append('Hello World!');

// 3. 만든 div의 자식 요소로 넣을 h1 태그를 만든다.
const txtH1 = document.createElement('H1');

// 4. 만든 h1에도 text를 넣어준다.
txtH1.textContent = '안녕하세요.';

// 5. 만든 h1을 div의 자식 요소로 추가해준다. (2가지 방법)
wrapDiv.append(txtH1);
wrapDiv.appendChild(txtH1);

// 6. 만들었던 h1을 삭제한다. (2가지 방법)
wrapDiv.removeChild(txtH1);
txtH1.remove();

2번) textContent는 말 그대로 태그 안에 text를 넣어주는 역할이다. 반면에 append()는 text뿐만 아니라 Node, 줄바꿈 등 모든 요소들을 넣어줄 수 있다. append()에 대한 건 6번에서 설명하였다.

 

5번) append()는 여러 개의 노드, 텍스트 등을 추가할 수 있는 반면 appendChild()는 오로지 노드만 추가할 수 있으며(텍스트 추가 불가능), 한 번에 오직 하나의 노드만 추가 가능하다. 따라서, 2번에서 append()를 통해 문자열 추가가 가능했던 것이다.

 

6번) removeChild()는 부모 노드를 기준으로 자식 노드를 끊어주는 역할을 한다. remove()는 삭제당하는 요소 기준에서 실행된다. 쉽게 말하면, 부모에게서 떨어지는 건 removeChild, 자기 스스로 삭제당하는 것은 remove이다.

 

const container = document.createElement('div');
const text = document.createElement('h1');
text.textContent = 'Hello World!';
container.appendChild('text');

const spanText = document.createElement('span');
text.after(spanText); // 뒤에 형제 요소로 추가
text.before(spanText); // 앞에 형제 요소로 추가

자식 요소로 추가 뿐만 아니라 형제 요소로도 추가할 수 있다. before()는 해당 요소의 앞 형제 요소로, after()는 뒤 형제 요소로 추가 된다.

 

DOM 선택(조회)하기

기본

<ul id="list" class="list">
    <li class="content">리스트 1</li>
    <li class="content">리스트 2</li>
    <li class="content">리스트 3</li>
</ul>
// Id로 선택하기
const list = document.getElementById('list');

// class로 선택하기
const list = document.getElementsByClassName('list')[0];

// TagName으로 선택하기
const list = document.getElementsByTagName('ul');

// querySelect 선택자로 선택하기 (3가지 방법)
const list = document.querySelector('ul');
const list = document.querySelector('.list');
const list = document.querySelector('#list');

// querySelectAll 선택자로 선택하기
const listAll = document.querySelectorAll('.content');
listAll.style.color = 'red' // 불가능
listAll.forEach((it) => it.style.color = 'red') // 전부 style 변경
listAll[0].style.color = 'red' // 0번 인덱스만 style 변경

DOM 요소를 선택하는 방법에는 id/class로 가져오는 방법과 querySelector로 가져오는 방법이 있다.

특히 getElementsByClassName()의 경우 복수의 class를 가져오는 것이므로 뒤에 [0] 식으로 인덱스를 붙여줘야

정상적으로 선택된다. (class가 1개여도 뒤에 인덱스를 붙여주지 않으면 에러가 난다.)

getElementsByTagName()도 class와 같이 복수이기 때문에 형식은 className과 같다.

 

querySelector의 경우 getElement로 가져오는 방식보다 더 자유롭다. 태그를 넣어줘도 되고, id/class명을 넣어줘도 된다. querySelectorAll의 경우 해당되는 요소를 전부 선택하는 선택자이다. 이것 역시 getElementsByClassName()처럼 복수 선택이기 때문에 querySelectorAll로 선택된 요소는 따로 forEach()인덱스 번호로 선택해줘야 한다.

 

자식 선택자

const list = document.getElementById('list');
const allList = list.children;
allList[0].style.color = 'red';

children을 통해 자식 요소를 선택할 수 있다. 간혹, children대신 childNodes를 쓰는 경우도 있다.

하지만, childNodes의 경우 자식 요소의 HTML 뿐만 아니라 줄바꿈(text), 주석 등 모든 노드를 포함시키기 때문에 딱히 효율적이게 보이지 않는다. 반면 children는 오직 HTML 요소만 반환하기 때문에 훨씬 활용하기 쉽다.

 

부모 선택자

<ul>
    <li class="content">리스트 1</li>
    <li class="content">리스트 2</li>
    <li class="content">리스트 3</li>
</ul>
const contents = document.getElementsByClassName('content');
const parents = contents[0].parentNode;
parents.style.border = "1px solid red";

부모 요소는 parentNode를 통해 간단히 선택할 수 있다.

 

형제 선택자

const contents = document.getElementsByClassName('content');
const prev = contents[1].previousSibling;
const next = contents[1].nextSibling;

console.log(prev.innerText); // #text
console.log(next.innerText); // #text

const prev2 = contents[1].previousSibling.previousSibling;
const next2 = contents[1].nextSibling.nextSibling;

console.log(prev.innerText); // li
console.log(next.innerText); // li

previousSibling은 현재 요소를 기준으로 앞의 노드를 가져오고, nextSibling은 현재 요소를 기준으로 뒤의 노드를 가져온다. 형제 선택자를 사용할 때 주의할 점은 우리가 코딩을 할 때, 줄바꿈 처리한 것도 노드로 인식하기 때문에 위의 예시처럼 li와 같이 HTML 요소를 선택할 때는 붙어 있지 않는 이상 형제 선택자를 2번 써줘야 우리가 생각한 결과를 얻을 수 있다.

 

DOM 수정하기

const text = document.createElement('h1');

// text 추가/변경하기
text.textContent = 'Hello World!';

// 속성과 값 추가/변경하기
text.setAttribute('id', 'text');

// class 추가/삭제하기
text.classList.add('bold-txt', 'grey-box');
text.classList.remove('grey-box');

textContent를 통해 해당 요소에 텍스트 요소를 넣어줄 수 있다. 만약, textContent를 중복으로 사용하는 경우 가장 뒤에 나온 textContent의 내용으로 수정된다. (중복 추가가 되지 않는다.)

 

setAttribute('속성', '값')은 태그의 속성과 값을 추가/변경해준다. 위의 코드를 예시로 하면, text 요소의 id는 'text'가 되는 것이다.

 

classList.add()로는 클래스를 추가해줄 수 있고, classList.remove()로는 클래스를 삭제할 수가 있다.

classList.add()의 경우 중복으로 사용되어도 변경되는 게 아니라 뒤에 계속 추가된다.

만약, 여러 클래스를 동시에 추가하고 싶을 때는 classList.add('클래스명1', '클래스명2', '클래스명3') 이런 식으로 추가해주면 된다.

 

1. createElement()로 태그를 생성하고,
2. appendChild() / append()로 DOM 트리를 구성한다.
3. textContent로 텍스트 요소를 넣어준다.
4. setAttribute()로 태그의 속성 값(id, class, name 등)을 넣어준다.