일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 카카오
- map
- 자바
- JavaScript
- 자바스크립트 코딩의 기술
- 리눅스
- Linux
- 프로그래머스
- 스프링 컨테이너
- GoingBus
- Memoir
- 명령어
- 반복문
- 코딩테스트
- 리눅스마스터 3과목
- Kotlin
- 월간코드챌린지
- 문자열
- 코테
- toCharArray
- Java
- 리눅스마스터 1급 정리
- 스프링 빈
- java 백준 1차원 배열
- 백준 java
- 백준 javascript
- 연습문제
- 고잉버스
- 리눅스마스터1급
- 개발자 회고록
- Today
- Total
hoon's bLog
Javascript 노드 Node 사용법 및 조작 본문
노드(node)
HTML DOM은 노드(node)라고 불리는 계층적 단위에 정보를 저장
HTML DOM은 이러한 노드들을 정의하고, 그들 사이의 관계를 설명해 주는 역할
HTML Node Tree
- HTML 문서의 정보는 노드 트리(node tree)라고 불리는 계층적 구조에 저장
- 노드들의 집합이며, 노드 간의 관계 표시
- 노드 트리는 최상위 레벨인 루트 노드(root node)로부터 시작하여, 가장 낮은 레벨인 텍스트 노드까지 내려감!
- 자바스크립트에서는 HTML DOM을 이용하여 노드 트리에 포함된 모든 노드에 접근가능
노드의 종류
W3C HTML DOM 표준에 따르면, HTML 문서의 모든 것은 노드!
- 문서 노드(document node) : HTML 문서 전체를 나타내는 노드임.
- 요소 노드(element node) : 모든 HTML 요소는 요소 노드이며, 속성 노드를 가질 수 있는 유일한 노드임.
- 속성 노드(attribute node) : 모든 HTML 요소의 속성은 속성 노드이며, 요소 노드에 관한 정보를 가지고 있음, 하지만 해당 요소 노드의 자식 노드(child node)에는 포함되지 않음.
- 텍스트 노드(text node) : HTML 문서의 모든 텍스트는 텍스트 노드
- 주석 노드(comment node) : HTML 문서의 모든 주석은 주석 노드임.
노드 간의 관계
- 노드 트리의 모든 노드는 서로 계층적 관계 형성
- 노드 트리의 가장 상위에는 단 하나의 루트 노드(root node)가 존재
- 루트 노드를 제외한 모든 노드는 단 하나의 부모 노드(parent node)만 존재
- 모든 요소 노드는 자식 노드(child node)를 가질 수 있음
- 형제 노드(sibling node) : 같은 부모 노드를 가지는 모든 노드 가리킴
- 조상 노드(ancestor node) : 부모 노드를 포함해 계층적으로 현재 노드보다 상위에 존재하는 모든 노드 가리킴
- 자손 노드(descendant node)란 자식 노드를 포함해 계층적으로 현재 노드보다 하위에 존재하는 모든 노드 가리킴
노드로의 접근
getElementsByTagName()
- 특정 태그 이름을 가지는 모든 요소를 노드 리스트의 형태로 반환
- 따라서 이 메서드가 반환하는 노드 리스트를 이용하면 원하는 노드에 접근가능
노드 간의 관계를 이용하여 접근하는 방법 : HTML DOM에서 노드 간의 관계는 다음과 같은 프로퍼티로 정의
- parentNode : 부모 노드
- childNodes : 자식 노드 리스트
- firstChild : 첫 번째 자식 노드
- lastChild : 마지막 자식 노드
- nextSibling : 다음 형제 노드
- previousSibling : 이전 형제 노드
노드에 대한 정보 : 다음과 같은 프로퍼티를 통해 접근가능
- nodeName : 노드 고유의 이름을 저장하므로, 수정할 수 없는 읽기 전용 프로퍼티
- 요소 노드의 nodeName 프로퍼티는 언제나 해당 HTML 요소의 태그 이름을 대문자로 저장
- 문서 노드(document node) : #document
- 요소 노드(element node) : 태그 이름 (영문자로 대문자)
- 속성 노드(attribute node) : 속성 이름
- 텍스트 노드(text node) : #text
- nodeValue : 노드의 값을 저장
- 요소 노드(element node) : undefined
- 속성 노드(attribute node) : 해당 속성의 속성값
- 텍스트 노드(text node) : 해당 텍스트 문자열
- 이러한 innerHTML 프로퍼티 대신에 firstChild.nodeValue를 사용해도 같은 결과
- nodeType : 노드 고유의 타입을 저장하므로, 수정할 수 없는 읽기 전용 프로퍼티
- 요소 노드(element node) : 1
- 속성 노드(attribute node) : 2
- 텍스트 노드(text node) : 3
- 주석 노드(comment node) : 8
- 문서 노드(document node) : 9
//HTML 문서의 모든 자식 노드 중에서 두 번째 노드의 이름을 선택
document.getElementById("document").innerHTML = document.childNodes[1].nodeName; // HTML
// html 노드의 모든 자식 노드 중에서 첫 번째 노드의 이름을 선택
document.getElementById("html").innerHTML = document.childNodes[1].childNodes[0].nodeName; // HEAD
// 위의 에서 HTML 문서의 첫 번째 자식 노드는 <!DOCTYPE html>이며, 두 번째 자식 노드는 <html>
// 또한, <html>노드의 첫 번째 자식 노드는 <head>이며, 세 번째 자식 노드는 <body>
// 아이디가 "heading"인 요소의 첫 번째 자식 노드의 노드값을 선택
var headingText = document.getElementById("heading").firstChild.nodeValue;
document.getElementById("text1").innerHTML = headingText;
document.getElementById("text1").firstChild.nodeValue = headingText;
// 아이디가 "heading"인 요소의 첫 번째 자식 노드의 타입을 선택
var headingType = document.getElementById("heading").firstChild.nodeType;
document.getElementById("head").innerHTML = headingType; // 3
document.getElementById("document").innerHTML = document.nodeType; // 9
빈 텍스트 노드의 처리
- 현재 대부분의 주요 웹 브라우저는 모두 W3C DOM 모델을 지원하지만, 그 처리 방식에 있어 약간씩의 차이 존재
- 그중에서도 가장 큰 차이점은 띄어쓰기와 줄 바꿈을 처리하는 방식
- 파이어폭스나 기타 브라우저들은 띄어쓰기나 줄 바꿈을 텍스트 노드(text node)로 취급
- 따라서 자식 노드나 형제 노드를 이용하여 원하는 노드에 접근하려고 하면 브라우저 간에 차이가 발생
- 이 차이를 없애는 가장 손쉬운 방법은 nodeType 프로퍼티를 사용하여 선택된 요소의 타입을 검사하는 것
var lastNode;
function findLastChild(parentNode) {
lastNode = parentNode.lastChild;
while (lastNode.nodeType != 1) {
lastNode = lastNode.previousSibling;
}
}
function printLastChild() {
var parentNode = document.getElementById("parentNode");
findLastChild(parentNode);
document.getElementById("nodename").innerHTML = lastNode.nodeName;
}
// 위의 에서 마지막 자식 노드를 찾은 후에, 찾은 노드의 타입이 요소 노드가 아니면 그 앞의 노드를 다시 검사
// 이 방식을 사용하면 모든 브라우저에서 마지막 자식 노드로 같은 요소 노드를 선택 가능
노드 리스트(node list)
- getElementsByTagName() 메서드나 childNodes 프로퍼티의 값으로 반환되는 객체
- 이 객체는 HTML 문서와 같은 순서로 문서 내의 모든 노드를 리스트 형태로 저장
- 리스트의 각 노드는 0부터 시작하는 인덱스를 이용하여 접근가능
// 아이디가 "list"인 요소의 모든 자식 노드들을 선택
var listItems = document.getElementById("list").childNodes;
// 자식 노드들 중 첫 번째 li 요소의 내용을 변경함.
listItems[1].firstChild.nodeValue = "HTML 요소의 내용을 변경했어요!";
- 위의 예제에서 자식 노드 중 첫 번째 <li>요소를 선택할 때 인덱스로 0이 아닌 1을 사용
- 그 이유는 HTML DOM에서 각 요소 노드 다음에는 별도의 텍스트 노드가 존재하기 때문
- 따라서 아이디가 "list"인 요소의 자식 노드 리스트의 첫 번째 노드에는 아이디가 "list"인 요소 다음에 존재하는 텍스트 노드가 저장
// 아이디가 "list"인 요소의 모든 자식 노드들을 선택
var listItems = document.getElementById("list").childNodes;
// 자식 노드들 중 첫 번째 노드의 값을 출력함.
document.write(listItems[0].nodeValue + "<br>");
// 자식 노드들 중 두 번째 노드의 자식 노드 중 첫 번째 노드의 값을 출력함.
document.write(listItems[1].firstChild.nodeValue + "<br>");
// 자식 노드들 중 세 번째 노드의 값을 출력함.
document.write(listItems[2].nodeValue);
- 위의 예제는 각 요소 노드 다음에 또 다른 텍스트 노드가 존재함을 표시
- 따라서 노드 리스트에 인덱스를 이용하여 접근할 때는 이러한 텍스트 노드의 존재를 반드시 염두!
- 노드 리스트 객체는 리스트에 노드를 추가하거나 삭제되면 자신의 상태 정보를 스스로 갱신
- 따라서 이 객체의 length 프로퍼티 값 = 언제나 노드 리스트가 저장하고 있는 노드들의 총 개수!
var listItems = document.getElementsByTagName("li"); // 모든 <li> 요소들을 선택
document.getElementById("text").innerHTML = "이 노드 리스트의 길이는 " + listItems.length + "개 <br>"; // 모든 자식 노드들의 개수를 반환함.
function changeTextColor() {
for (var i = 0; i < listItems.length; i++) {
listItems[i].style.color = "orange"; // 모든 자식 노드들의 글자색을 변경함.
}
}
appendChild() : 새로운 노드를 해당 노드의 자식 노드 리스트(child node list)의 맨 마지막에 추가
function appendNode() {
var parent = document.getElementById("list"); // 아이디가 "list"인 요소를 선택
var newItem = document.getElementById("item"); // 아이디가 "item"인 요소를 선택
parent.appendChild(newItem); // 해당 요소의 맨 마지막 자식 노드로 추가함.
}
insertBefore() : 새로운 노드를 특정 자식 노드 바로 앞에 추가
부모노드.insertBefore(새로운 자식 노드, 기준 자식 노드);
- 새로운 자식 노드 : 자식 노드 리스트(child node list)에 새롭게 추가할 자식 노드를 전달
- 기준 자식 노드 : 새로운 노드를 삽입할 때 기준이 되는 노드로, 이 노드 바로 앞에 새로운 노드가 추가
- 기준 자식 노드에 null 값을 전달하면 새로운 노드는 자식 노드 리스트의 맨 마지막 노드로 추가
- 즉, appendChild() 메서드와 완전히 같은 동작!
function appendNode() {
var parent = document.getElementById("list"); // 아이디가 "list"인 요소를 선택
var criteriaItem = document.getElementById("criteria"); // 아이디가 "criteria"인 요소를 선택
var newItem = document.getElementById("item"); // 아이디가 "item"인 요소를 선택
parent.insertBefore(newItem, criteriaItem); // 해당 노드를 기준이 되는 자식 노드의 바로 앞에 추가함.
}
insertData() : 텍스트 노드의 텍스트 데이터에 새로운 텍스트를 추가
텍스트노드.insertData(오프셋, 새로운 데이터);
- 오프셋(offset) : 오프셋 값은 0부터 시작하며, 기존 텍스트 데이터의 몇 번째 위치부터 추가할지를 전달
- 새로운 데이터 : 새로이 삽입할 텍스트 데이터를 전달
var text = document.getElementById("text").firstChild; // 아이디가 "text"인 요소의 텍스트 노드를 선택
function appendText() {
text.insertData(6, " 나른한 "); // 텍스트 노드의 6번째 문자부터 " 나른한 "이란 텍스트를 추가함.
}
요소 노드의 생성 : createElement() 메서드를 사용하여 새로운 요소 노드 생성
function createNode() {
var criteriaNode = document.getElementById("text"); // 기준이 되는 요소로 아이디가 "text"인 요소를 선택
var newNode = document.createElement("p"); // 새로운 <p> 요소를 생성함.
newNode.innerHTML = "새로운 단락";
document.body.insertBefore(newNode, criteriaNode); // 새로운 요소를 기준이 되는 요소 바로 앞에 추가함.
}
속성 노드의 생성 : createAttribute() 메서드를 사용하여 새로운 속성 노드 생성
- 만약 같은 이름의 속성 노드가 이미 존재하면, 기존의 속성 노드는 새로운 속성 노드로 대체
- 이미 존재하는 요소 노드에 속성 노드를 생성 할 때에는 setAttribute() 메서드를 사용가능
function createNode() {
var text = document.getElementById("text"); // 아이디가 "text"인 요소를 선택
var newAttribute = document.createAttribute("style"); // 새로운 style 속성 노드를 생성함.
newAttribute.value = "color:red";
text.setAttributeNode(newAttribute); // 해당 요소의 속성 노드로 추가함.
}
텍스트 노드의 생성 : createTextNode() 메서드를 사용하여 새로운 텍스트 노드를 만들 수 있습니다.
function createNode() {
var elementNode = document.getElementById("text"); // 아이디가 "text"인 요소를 선택
var newText = document.createTextNode("새로운 텍스트!"); // 새로운 텍스트 노드를 생성함.
elementNode.appendChild(newText); // 해당 요소의 자식 노드로 추가함.
}
노드의 제거
removeChild() : 자식 노드 리스트에서 특정 자식 노드를 제거
- 이 메서드는 성공적으로 노드가 제거되면 제거된 노드를 반환
- 노드가 제거될 때에는 제거되는 노드의 모든 자식 노드들도 다 같이 제거
var parent = document.getElementById("list"); // 아이디가 "list"인 요소를 선택
var removedItem = document.getElementById("item"); // 아이디가 "item"인 요소를 선택
parent.removeChild(removedItem); // 지정된 요소를 삭제함.
removeAttribute() : 속성의 이름을 이용하여 특정 속성 노드를 제거
var text = document.getElementById("text"); // 아이디가 "text"인 요소를 선택
text.removeAttribute("style"); // 해당 요소의 "style" 속성을 제거함.
노드의 복제
cloneNode() : 기존의 존재하는 노드와 똑같은 새로운 노드를 생성하여 반환
복제할노드.cloneNode(자식노드복제여부);
- 자식 노드 복제 여부 : 전달된 값이 true이면 복제되는 노드의 모든 속성 노드와 자식 노드도 같이 복제
- false이면 속성 노드만 복제하고, 자식 노드는 복제하지 않음
function cloneElement() {
var parent = document.getElementById("list"); // 아이디가 "list"인 요소를 선택
var originItem = document.getElementById("item"); // 아이디가 "item"인 요소를 선택
parent.appendChild(originItem.cloneNode(true)); // 해당 노드를 복제하여 리스트의 맨 마지막에 추가함.
}
노드의 조작
- 노드의 값 변경 : nodeValue 프로퍼티를 사용하면 특정 노드의 값을 변경가능
- 또한, setAttribute() 메서드는 속성 노드의 속성값을 변경 가능
- 요소 노드의 텍스트 : 요소 노드는 자신이 직접 텍스트값 X
- 요소 노드의 텍스트는 요소 노드의 자식 노드인 텍스트 노드(text node)에 저장
- 따라서 요소 노드의 텍스트 값을 확인하거나 변경 할 때는 요소 노드에 포함된 텍스트 노드에 접근해야 함!
- 텍스트 노드의 값 변경 : nodeValue 프로퍼티를 사용하여 텍스트 노드의 값을 변경 가능
var para = document.getElementById("text"); // 아이디가 "text"인 요소를 선택
function changeText() {
para.firstChild.nodeValue = "텍스트 변경 완료!";
}
- 속성 노드의 값 변경 : nodeValue 프로퍼티뿐만 아니라 setAttribute() 메서드를 사용하여 값을 변경가능
- setAttribute() 메서드는 속성값을 변경하려는 속성이 존재하지 않으면, 먼저 해당 속성을 생성한 후에 속성값을 설정
var para;
function changeAttribute() {
// 모든 <p> 요소 중에서 첫 번째 요소에 클래스 속성값으로 "para"를 설정함.
document.getElementsByTagName("p")[0].setAttribute("class", "para");
// 클래스가 설정되면 해당 클래스에 설정되어 있던 스타일이 자동으로 적용됨.
}
요소 노드의 교체
replaceChild() 메서드를 사용하면 기존의 요소 노드를 새로운 요소 노드로 교체가능
교체할 노드 = 부모노드.replaceChild(새로운 자식 노드, 기존 자식 노드);
- 새로운 자식 노드 : 자식 노드 리스트에 새롭게 추가할 요소 노드를 전달
- 기존 자식 노드 : 자식 노드 리스트에서 제거할 요소 노드를 전달
var parent = document.getElementById("parent"); // 부모 노드를 선택
var first = document.getElementById("first");
var third = document.getElementById("third");
function changeNode() {
parent.replaceChild(third, first); // first 요소를 삭제하고, 그 대신 third 요소를 삽입함.
}
replaceData() : 사용하면 텍스트 노드의 텍스트 데이터를 교체 가능
텍스트노드.replaceData(오프셋, 교체할 문자수, 새로운 데이터);
- 오프셋(offset) : 오프셋 값은 0부터 시작하며, 기존 텍스트 데이터의 몇 번째 문자부터 교체할지를 전달
- 교체할 문자 수 : 기존 텍스트 노드의 데이터로부터 교체할 총 문자 수를 전달
- 새로운 데이터 : 새로이 삽입할 텍스트 데이터를 전달
var text = document.getElementById("text").firstChild; // 아이디가 "text"인 요소의 텍스트 노드를 선택
function changeText() {
text.replaceData(7, 4, "저녁 7"); // 텍스트 노드의 7번째 문자부터 4개 문자를 "저녁 7"로 교체함.
}
Reference
https://www.tcpschool.com/javascript/js_dom_node
'IT > Javascript' 카테고리의 다른 글
Javascript 이벤트, 이벤트 리스너 개념 및 사용 (0) | 2023.06.29 |
---|---|
Javascript BOM 브라우저 객체 모델 사용 (0) | 2023.06.18 |
Javascript 문서 객체 모델 DOM 객체 (0) | 2023.06.15 |
Javascript Array 객체 Object (0) | 2023.06.14 |
Javascript 객체 Object 전역객체(global object), 래퍼객체(wrapper object), 객체 메서드 (0) | 2023.06.12 |