[Web/JS] 자바스크립트 - DOM에서의 노드 추가 및 삭제
✏️ 노드 리스트
DOM에 접근할 때 querySelectorAll() 메서드를 사용하면 노드를 한꺼번에 여러 개 가져올 수 있습니다. 이때 노드 정보를 여러 개 저장한 것을 노드 리스트라고 하고 배열과 비슷하게 동작할 수 있습니다. 예제를 통해서 접근해보겠습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web Programming</title>
<link rel="stylesheet" href="css/nodelist.css">
</head>
<body>
<h1>Web Programming</h1>
<ul id="itemList">
<li>HTML</li>
<li>CSS</li>
<li>Javascript</li>
</ul>
</body>
</html>
위의 코드를 실행한 후 F12 키를 눌러서 콘솔 창에 document.querySelectorAll("li")를 입력한 모습입니다. querySelectorAll()은 노드 리스트를 반환하기 때문에 화면 출력 결과에서 Nodelist(3) [li, li, li]가 출력되었습니다. 이렇게 입력을 하면 노드 리스트뿐만 아니라 인덱스와 요솟값이 저장되고 length 속성에서 몇 개의 노드가 저장되어 있는지 알 수 있습니다. 또한 노드 리스트는 배열처럼 특정 인덱스로 접근할 수 있습니다.
✏️ 새로운 노드 추가하기
노드를 추가하기 전에 DOM 트리를 구성하는 기본 원칙을 한 번더 상기시켜보겠습니다.
- 모든 HTML 태그는 요소(element) 노드입니다.
- HTML 태그에서 사용하는 텍스트 내용은 자식 노드인 텍스트(text) 노드입니다.
- HTML 태그에 있는 속성은 자식 노드인 속성(attribute) 노드입니다.
- 주석은 주석(comment) 노드입니다.
이 원칙에 따라 어떠한 태그를 노드로 추가한다면 단순히 태그에 해당하는 요소 노드뿐안 아니라 텍스트 노드와 속성 노드도 추가해야합니다. 즉 새로운 노드를 추가할 때는 웹 문서에 어떤 소스를 추가할지 먼저 생각하고, 그에 따라 요소 노드나 텍스트, 속성 노드 등을 만들어야 합니다.
✏️ 텍스트 노드를 사용하는 새로운 요소 추가하기
#1 요소 노드 만들기 - createElement() 메서드
요소 노드는 createElement() 메서드를 사용하여 괄호 안에 해당하는 요소 노드를 만들 수 있습니다.
기본형 => document.createElement(노드명)
var newP = document.createElement("p")
// 이렇게 생성을 하게 되면 새로운 노드만 만들었을 뿐이지 아직 웹 문서에 새로운 노드를 추가한 것이 아닙니다. 코드에서 p 요소를 만들었으므로 <p> 태그의 내용에 해당하는 텍스트 노드를 만들어야 합니다.
#2 텍스트 노드 만들기 - createTextNode() 메서드
새로운 요소 노드를 만들었다면 내용을 담는 텍스트 노드를 자식 노드로 만들어 연결시켜주어야 합니다.
기본형 => document.createTextNode(텍스트);
var txtNode = document.createTextNode("DOM은 document object Model의 줄임말");
// 위에서 만들었던 p요소에 담을 내용이 있는 텍스트 노드를 txtNode 변수로 저장하겠습니다.
#3 자식 노드 연결하기 - appendChild() 메서드
현재까지 새로운 p노드(newP)와 사용할 텍스트 노드(txtNode)를 만들었습니다. 이제는 이 두개의 노드를 연결시켜주어야 할 차례입니다. 이때 appendChild() 메서드를 사용해서 두 개의 노드를 연결시킬 수 있습니다. 이때, 연결하는 자식 노드는 부모 노드의 자식 노드 중에서 가장 맨 끝에 추가됩니다.
기본형 => 부모노드.appendChild(자식 노드)
newP.appendChild(txtNode);
document.getElementById("info").appendChild(newP);
// 텍스트 노드 txtNode를 요소 노드 newP의 자식 노드로 연결하고, newP 노드를 다시 <div id = "info"></div>의 자식 노드로 연결해주겠습니다.
#4 전체 소스 코드 완성하기
더 보기 버튼을 누르면 노드를 연결해주도록 해주는 예제입니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>DOM</title>
<style>
#container{
width:500px;
margin:10px auto;
padding:20px;
}
#info {
margin-top:20px;
}
</style>
</head>
<body>
<div id="container">
<h1>DOM을 공부합시다</h1>
<a href="#" onclick="addP(); this.onclick='';">더 보기</a>
<div id="info"></div>
</div>
<script>
function addP() {
var newP = document.createElement("p");
var txtNode = document.createTextNode("DOM은 Document Object Model의 줄임말입니다.");
newP.appendChild(txtNode);
document.getElementById("info").appendChild(newP);
}
</script>
</body>
</html>
✏️ 속성값이 있는 새로운 요소 추가하기
1. 요소 노드 만들기 - createElement() 메서드
위에서 했던 것처럼 createElement() 메서드를 사용해서 새로운 이미지 노드를 만들어보겠습니다.
var newImg = document.createElement("img");
#2 속성 노드 만들기 - createAttribute() 메서드
img 요소는 src 속성을 사용해서 이미지 파일의 경로를 지정해야 브라우저에 이미지를 보여줄 수 있기 때문에 createAttribute() 메서드를 사용해서 속성 노드를 만들어 주어야 합니다. 이미지 파일의 경로를 지정할 src와 대체 텍스를 지정할 alt를 위해 속성 노드를 추가하겠습니다.
var srcNode = document.createAttribute("src");
var altNode = document.createAttribute("alt");
srcNode.value = "images/dom.jpg";
altNode.value - "돔 트리 예제 이미지";
#3 속성 노드 연결하기 - setAttributeNode() 메서드
텍스트 노드를 연결할 때 부모 노드와 자식 노드를 연결한 것처럼 속성 노드는 요소 노드의 자식으로 연결해 주어야 합니다. setAttributeNode() 메서드를 이용해서 새로 만든 속성 노드를 요소 노드에 추가할 수 있습니다. 만약 추가할 속성이 요소 노드에 이미 들어 있다면 기존 속성 노드로 대체합니다. newImg라는 새 요소를 만들고 srcNode라는 속성 노드를 추가하겠습니다.
newImg.setAttributeNode(srcNode);
4. 자식 노드 연결하기 - appendChild() 메서드
속성 노드끼리는 연결했지만 아직 img 요소는 만들어 놓기만 한 상태입니다. img 요소를 화면에 표시하기 위해서는 웹 문서의 DOM에 추가해야 하므로 appendChild() 메서드를 이용해서 연결해야 합니다. #info 위치에 새로 만든 img 요소를 자식 요소로 추가하겠습니다.
document.getElementById("info").appendChild(newImg);
#5. 전체 소스 코드 완성하기
// <a> 태그에 있는 더 보기 링크를 클릭하면 <p> 태그를 사용한 텍스트와 images/dom.jpg이미지를 표시하는 예제입니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>DOM</title>
<style>
#container{
width:500px;
margin:10px auto;
padding:20px;
}
#info {
margin-top:20px;
}
</style>
</head>
<body>
<div id="container">
<h1>DOM을 공부합시다</h1>
<a href="#" onclick="addContents(); this.onclick='';">더 보기</a>
<div id="info"></div>
</div>
<script>
function addContents() {
var newP = document.createElement("p");
var txtNode = document.createTextNode("DOM은 Document Object Model의 줄임말입니다.");
newP.appendChild(txtNode);
var newImg = document.createElement("img");
var srcNode = document.createAttribute("src");
var altNode = document.createAttribute("alt");
srcNode.value = "images/dom.jpg";
altNode.value = "돔 트리 예제 이미지";
newImg.setAttributeNode(srcNode);
newImg.setAttributeNode(altNode);
document.getElementById("info").appendChild(newP);
document.getElementById("info").appendChild(newImg);
}
</script>
</body>
</html>
✏️ 노드 삭제하기
위에서는 노드를 추가하고 연결하는 것을 알아봤다면 이번에는 DOM 트리에서 특정 노드를 삭제하는 방법을 알아보겠습니다. 노드를 삭제할 때 중요한 점은 부모 노드에서 자식 노드를 삭제해야 한다는 점입니다. 이 말은 삭제하는 노드가 있다면 반드시 부모 노드를 먼저 찾아야 한다는 말입니다. 그래서 노드를 삭제하는 메서드 위에 부모 노드를 찾아주는 프로퍼티가 필요합니다.
#1. parentNode 프로퍼티
이 프로퍼티는 현재 노드의 부모 노드에 접근해서 부모 노드의 요소를 반환해줍니다.
기본형 => 노드.parentNode
#2. removeChild() 메서드
부모 노드를 찾았다면 이제는 removeChild() 메서드를 이용해서 자식 노드를 삭제할 차례입니다.
기본형 => 부모노드.removeChild(자식노드)
// 예를 들어 li 노드를 삭제하려면 li의 부모 노드에서 삭제해야 합니다.
li.parentNode.removeChild(li);