텍스트 조작
API | 설명 |
nodeValue | 노드의 텍스트 값을 변경한다. 텍스트 노드를 선택해야만 텍스트를 변경할 수 있다. |
textContent | 요소노드의 텍스트 노드를 변경한다. HTML 마크업을 파싱하지 않는다. |
innerText | textContent 와 마찬가지로 텍스트 노드를 변경한다. textContent 보다 느리고 CSS 에 영향을 받는다. 사용하지 않는 것이 좋다. |
nodeValue
<body>
<div id="app">Hello</div>
<script>
const $app = document.querySelector("#app");
// nodeValue
console.log($app.nodeValue); // null
console.log($app.firstChild.nodeValue); // Hello
// chage text
$app.firstChild.nodeValue = "world";
console.log($app.firstChild.nodeValue) // world
</script>
</body>
textContent
<body>
<div id="app">
Hello
<span>World</span>
</div>
<script>
const $app = document.querySelector("#app");
// nodeValue
console.log($app.textContent); // Hello World
// chage text
$app.textContent = "Good";
console.log($app.textContent) // Good;
$app.textContent = '<div> Good </div>';
console.log($app.textContent) // <div> Good </div>;
</script>
</body>
내부에 요소 노드가 존재하여도 text 형태 노드만 반환한다.
내부에 텍스트를 삽입하면 모든 자식 노드가 제거되고 할당된 텍스트가 추가된다.
HTML 마크업 형태를 파싱하지 않는다.
DOM 조작
새로운 돔 노드가 추가, 생성, 삭제시 리플로우와 리페인트가 발생하여 성능에 영향을 끼친다.
최적화에 신경 써야 한다.
API | 설명 |
innerHTML | 콘텐츠 영역 내에 값을 취득, 변경한다. HTML 마크업을 문자열로 변환한다. |
insertAdjacentHTML | 기존 요소를 제거하지않고 위치를 지정해 요소를 삽입한다. |
innerHTML
<body>
<div id="app">
Hello
<span>World</span>
</div>
<script>
const $app = document.querySelector("#app");
console.log($app.innerHTML); // Hello \n <span>World</span>
$app.innerHTML = `<span> new World </span>`;
console.log($app.innerHTML); // <span> new World </span>
</script>
</body>
조회시 내부 text 와 요소노드 모두 포함하여 있는 그대로 돌려준다.
HTML 텍스트 삽입시 파싱되어 내부에 직접 적용된다.
<body>
<ul id="app">
<li>apple</li>
</ul>
<script>
const list = ["banana", "orange"];
const $app = document.querySelector("#app");
for(let i = 0 ; i < list.length ; i++){
$app.innerHTML += `<li>${list[i]}</li>`;
}
</script>
</body>
배열을 통해 여러 노드를 생성한다.
innerHTML 은 조작이 간단하고 직관적이나 크로스 사이트 스크립팅 공격에 취약하다.
insertAdjacentHTML
기존 요소를 제거하지 않고 새로운 요소를 지정된 위치에 삽입한다.
첫 번째 인자로 InsertPosition, 두번째 인자로 문자열을 넣는다.
첫 번째 인자의 종류로는 "beforebegin", "afterbegin", "beforeend", "afterend" 이다.
각각의 삽입 위치는 아래와 같다.
<!-- beforebegin -->
<div id="app">
<!-- afterbegin -->
<span>Hello</span>
<!-- beforeend -->
</div>
<!-- afterend -->
<body>
<div id="app">
<p>Hello</p>
</div>
<script>
const $app = document.querySelector("#app");
$app.insertAdjacentHTML('beforebegin', "<p> beforebegin </p>");
$app.insertAdjacentHTML('afterbegin', "<p> afterbegin </p>");
$app.insertAdjacentHTML('beforeend', "<p> beforeend </p>");
$app.insertAdjacentHTML('afterend', "<p> afterend </p>");
</script>
</body>
innerHTML 과 마찬가지로 마크업 문자열을 파싱하고 크로스 사이트 스크립팅 공격에 취약하다.
노드 생성
API | 설명 |
createElement | 요소 노드를 생성한다. |
createTextNode | 텍스트 노드를 생성한다. |
createDocumentFragment | 부모노드 대신 사용한다. 기존 DOM 에 추가하기 위한 용도로 사용 |
<body>
<div id="app"></div>
<script>
const $app = document.querySelector("#app");
const $p = document.createElement("span");
const textNode = document.createTextNode("Hello");
$p.append(textNode);
$app.append($p);
</script>
</body>
createElement 로 생성한 요소노드는 생성됐을뿐 DOM 트리에 달려 있지 않다.
따라서 DOM 트리에 추가해야 한다.
TextNode 도 마찬가지로 생성된후 별도의 DOM 트리 추가 작업이 필요하다.
// 텍스트 노드 생성후 자식 노드로 추가
$li.appendChild(document.createTextNode("apple"));
// 직접 추가
$li.textContent = "apple";
여러 노드 생성
<body>
<ul id="app"></ul>
<script>
const $app = document.querySelector("#app");
const list = ["apple", "banana", "orange"];
list.forEach((v, i) => {
const $li = document.createElement("li"); // li 노드 생성
const textNode = document.createTextNode(v); // 텍스트 노드 생성
$li.appendChild(textNode); // li 노드에 text 노드 삽입
$app.appendChild($li); // 완성된 li 노드를 $app 노드에 삽입
});
</script>
</body>
계속해서 DOM 요소에 추가하는 것은 비용이 큰 작업이다. 따라서 아래와 같이 해결할 수 있다.
createDocumentFragment
<body>
<ul id="app"></ul>
<script>
const $app = document.querySelector("#app");
const list = ["apple", "banana", "orange"];
const $fragment = document.createDocumentFragment();
list.forEach((v, i) => {
const $li = document.createElement("li"); // li 노드 생성
const textNode = document.createTextNode(v); // 텍스트 노드 생성
$li.appendChild(textNode); // li 노드에 text 노드 삽입
$fragment.appendChild($li); // 완성된 li 노드를 $fragment 에 삽입
});
$app.appendChild($fragment);
</script>
</body>
노드 삽입
API | 설명 |
append | 인자로 전달받은 노드를 마지막 자식노드로 추가한다. |
appendChild | 인자로 전달받은 노드를 마지막 자식노드로 추가한다. 단 노드 형태가 아니면 랜더링 되지 않는다. |
insertBefore | 첫번째 인수로 전달받은 노드를 두번째 인수로 전달받은 노드 앞에 삽입한다. |
append
<body>
<ul id="app"></ul>
<script>
const $app = document.querySelector("#app");
const $span = document.createElement("span");
$span.textContent = "Hi";
$app.append("Hello");
$app.append($span);
$app.append("<p>Good</p>");
</script>
</body>
전달받은 인자를 마지막에 추가한다. HTML 형태로 마크업 하지 않으며 text 형태를 직접 사용가능하다.
appendChild
<body>
<ul id="app"></ul>
<script>
const $app = document.querySelector("#app");
const $span = document.createElement("span");
$span.textContent = "Hi";
const $text = document.createTextNode("Hello");
$app.appendChild("Hello"); // Error, parameter 1 is not of type 'Node'.
$app.appendChild($span);
$app.appendChild($text);
$app.appendChild("<p>Good</p>"); // Error, parameter 1 is not of type 'Node'.
</script>
</body>
Node 형태만 삽입이 가능하다. text도 text node 로 생성후 삽입해야한다.
insertBefore
<body>
<ul id="app">
<li>a</li>
<li>b</li>
</ul>
<script>
const $app = document.querySelector("#app");
const $li = document.createElement("li");
$li.appendChild(document.createTextNode("c"));
$app.insertBefore($li, $app.lastElementChild);
</script>
</body>
반드시 insertBefore 메소드를 호출한 노드의 자식노드여야 한다.
노드 복사
API | 설명 |
cloneNode | 노드의 사본을 생성하여 반환한다. 매개변수에 true 를 전달시 노드를 깊은 복사하여 모든 자손이 생성된 사본을 생성하고 false 시 얉은복사하여 자신의 사본만 전달된다. default : false |
<body>
<ul id="app">
<li>red</li>
</ul>
<script>
const $app = document.querySelector("#app");
const $shallowClone = $app.firstElementChild.cloneNode();
$shallowClone.textContent = "blue";
$app.appendChild($shallowClone);
const $deepClone = $app.cloneNode(true);
$app.appendChild($deepClone);
</script>
</body>
노드 교체
API | 설명 |
replaceChild | 자신이 호출한 노드의 자식노드를 다른 노드로 교체한다. 첫 번째 인자로 교체할 새로운 노드를, 두 번째 인자로 교체될 노드를 전달한다. |
<body>
<ul id="app">
<li>red</li>
</ul>
<script>
const $app = document.querySelector("#app");
const $newNode = document.createElement("li");
$newNode.appendChild(document.createTextNode("new Red"));
$app.replaceChild($newNode, $app.firstElementChild);
</script>
</body>
노드 제거
API | 설명 |
removeChild | 인수로 전달한 노드를 DOM 에서 제거한다. 인수로 전달한 노드는 호출한 노드의 자식 노드여야한다. |
remove | 본인까지 포함하여 해당 돔을 완전히 제거해버린다. |
removeChild
<body>
<ul id="app">
<li>red</li>
<li>blue</li>
</ul>
<script>
const $app = document.querySelector("#app");
$app.removeChild($app.lastElementChild); // #li blue 노드 삭제
</script>
</body>
자식노드 전부 제거 방법
<body>
<ul id="app">
<li>red</li>
<li>blue</li>
</ul>
<script>
const $app = document.querySelector("#app");
while($app.hasChildNodes()){
$app.removeChild($app.firstChild);
}
</script>
</body>
innerHTML 을 사용한 방법
<body>
<ul id="app">
<li>red</li>
<li>blue</li>
</ul>
<script>
const $app = document.querySelector("#app");
$app.innerHTML ="";
</script>
</body>
remove
<body>
<ul id="app">
<li>red</li>
<li>blue</li>
</ul>
<script>
const $app = document.querySelector("#app");
$app.remove(); // 본인까지 포함하여 삭제
</script>
</body>
Reference
- 모던 자바스크립트 - 이웅모
There might be incorrect information or outdated content.
'Web > Javascript' 카테고리의 다른 글
[JAVASCRIPT] try-catch 에러 전파 (0) | 2023.08.15 |
---|---|
[JAVASCRIPT] isNaN 검사 (0) | 2023.08.15 |
[JAVASCRIPT] DOM - 노드 탐색 (0) | 2023.08.04 |
[JAVASCRIPT] DOM - 노드 취득 (HTMLCollection) (0) | 2023.08.04 |
[JAVASCRIPT] Full Screen (0) | 2023.07.29 |