목차
Text 및 HTML 변경
JavaScript를 사용해 텍스트나 콘텐츠를 변경해야 할 때가 있다. 선택된 DOM 요소의 텍스트 콘텐츠나 HTML을 변경할 때 다음 두 가지 방법을 사용한다.
- .textContent 속성: DOM 요소의 텍스트 콘텐츠 변경. HTML 태그는 무시하고 텍스트만 변경하기 때문에 사용자 메시지나 안내문 등을 수정할 때 주로 사용한다.
- .innerHTML 속성: DOM 요소 내부의 HTML 변경. HTML 태그를 해석하여 HTML 구조를 포함한 콘텐츠를 변경하기 때문에 버튼, 리스트, 카드 등을 수정할 때 주로 사용한다.
// .textContent로 DOM 요소 텍스트 콘텐츠 변경
const element = document.querySelector('.element')
element.textContent = 'DOM 요소 텍스트 콘텐츠 변경'
// .innerHTML로 DOM 요소 내부의 HTML 변경
const element = document.querySelector('.element')
element.innerHTML = '<p class="important">DOM 요소 HTML 변경</p>'
// 템플릿 리터럴을 사용하면 여러 줄 작성 가능
element.innerHTML = `
<ul class="italian-menu">
<li>피자</li>
<li>파스타</li>
<li>리조또</li>
</ul>
`
DOM에 요소 추가
DOM에 요소를 추가하려면 먼저 요소부터 생성해야 한다. 요소는 .createElemet() 메서드를 사용해서 생성할 수 있다. 생성한 요소에 속성이나 콘텐츠를 추가할 수 있다.
// 요소 생성
const unorderedList = document.createElement('ul')
const paragraph = document.createElement('p')
// 생성된 요소에 속성과 콘텐츠 추가
unorderedList.classList.add('reviews')
paragraph.textContent = '2025년 신상품은 기존 자사 상품 대비 12% 가량 더 빠릅니다.'
DOM에 요소를 추가하려면 다음 메서드들을 사용할 수 있다.
- .appendChild(): 전달된 요소를 지정된 요소의 마지막 자식 요소로 추가. 이미 DOM에 있는 요소를 추가하면 기존 위치에서 지정한 새 위치로 이동한다.
- .insertBefore(): 먼저 전달된 삽입요소를 다음 전달된 목표요소 바로 앞에 추가. 이미 DOM에 있는 요소를 추가하면 기존 위치에서 목표 요소 바로 앞으로 이동한다.
부모요소.appendChild(자식요소) // 부모요소의 마지막 자식요소로 추가됨
부모요소.insertBefore(삽입요소, 목표요소) // 목표요소 바로 앞에 삽입요소 추가
DOM에 여러 요소 추가
DOM에 요소를 추가하면 추가한 요소 뒤에 있는 모든 것을 브라우저에서 다시 렌더링해야 하기 떄문에 비용이 많이 든다. 가능하면 DOM에 요소를 추가하는 일을 적게 사용하는 것이 좋다.
.appendChild()와 .insertBefore() 메서드 외에도 유용한 요소의 메서드는 다음과 같다.
- .prepend(): 요소의 첫 번째 자식 요소 뒤에 다른 요소(들) 삽입
- .append(): 요소의 마지막 자식 요소 뒤에 다른 요소(들) 삽입
- .before(): 요소 앞에 다른 요소(들) 삽입
- .after(): 요소 뒤에 다른 요소(들) 삽입
- .insertAdjacentElement(): 특정 위치에 요소 삽입
- .insertAdjacentHTML(): 특정 위치에 HTML 삽입
DOM에 여러 요소를 한 번에 추가하면 각 요소를 여러 번 추가하는 것보다 비용이 적게 든다. .innerHTML 속성을 사용하여 DOM 내부의 HTML을 한 번에 변경하는 방법도 있다. 단, 요소의 HTML을 모두 변경하기 때문에 변경될 필요가 없는 요소도 교체될 수 있다. 이럴 때는 DocumentFragment(문서 조각) 객체를 사용하는 것이 더 나을 수 있다.
DocumentFragment(문서 조각) 객체는 실제 DOM과 동일하게 작동하는 가상 DOM 조각을 활용하여 한 번에 DOM에 추가한다. createDocumentFragment() 메서드를 사용해서 객체를 생성하고 .appendChild()와 .insertBefore() 메서드를 사용해 요소를 추가할 수 있다. DocumentFragment 객체의 변경 사항은 실제 DOM에 추가하기 전까지는 비용이 발생하지 않는다. 객체 만들기를 완료한 후에 .appendChild()와 .insertBefore() 메서드를 사용해 DOM을 업데이트하면 된다.
// Document Fragment(문서 조각) 생성
const fragment = document.createDocumentFragment()
// Document Fragment에 요소 추가
people.forEach((person) => {
const item = document.createElement('li')
item.innerHTML = person
fragment.appendChild(item)
})
// 한 번에 DOM 업데이트
members.appendChild(fragment)
DOM에서 요소 제거
DOM에서 요소를 제거하려면 .removeChild() 메서드를 사용한다. members라는 클래스를 가진 <ul>(부모 요소)에서 세 번째 <li>(자식 요소)를 찾아 제거하려면 다음과 같이 코드를 작성할 수 있다.
const members = document.querySelector('.members')
const thirdChild = members.children[2]
members.removeChild(thirdChild)
.removeChild() 메서드는 제거한 요소를 반환하기 때문에 제거한 요소를 .appendChild()나 .insertBefore() 메서드를 사용해서 다른 요소의 자식이나 앞 위치에 이동할 수 있다.
const members = document.querySelector('.members')
const firstChild = members.children[0]
const lastChild = [...members.children].at(-1)
const removedMember = members.removeChild(lastChild)
// 마지막 자식 요소를 첫 번째 요소 앞으로 이동
members.insertBefore(removedMember, firstChild)
.removeChild() 메서드 대신 .remove() 메서드를 사용할 수도 있지만, .remove() 메서드는 undefined를 반환하기 때문에 반환 값이 필요하다면 .removeChild() 메서드를 사용한다.
오늘 하루를 돌아보며
뭔가 본격적으로 개발자 같은 것을 배운 것 같다. HTML에는 없는 구조를 JavaScript만 사용해서 만들어 넣고, 추가하고 지우기도 하는 작업이 신기하고 재밌었다. 어제까지만 해도 내용도 머리에 잘 안 들어오고 어려웠는데 오늘은 그래도 눈에 보이는 작업이라 집중이 잘 됐다.
마냥 재밌어서 내용도 다 이해한 줄 알았는데 실습 문제들을 풀다 보니 뇌가 생각을 멈췄다. 분명 이해한 것 같았는데 막상 직접 문제를 풀어보려고 하니까 기억이 안 나고, 이게 맞나 싶었다. 아직 익숙하지 않아서 그런 건지, 개념이 이해가 안 되는 게 있는 건지도 잘 모르곘다. 이따 저녁에 다시 실습 문제들을 풀어보면서 모르는 게 뭔지, 단지 익숙하지 않아서 그런 건지 알아내야지!