DOM 조작
- DOM조작이란 새로운 노드를 생성하여 DOM에 추가하거나, 기존 노드를 삭제 또는 교체하는것을 말한다.
- 성능에 영향을 주므로 최적화를 위해 주의하여 다뤄야한다.
innerHTML
- 요소내에 포함된 HTML마크업을 가져오거나 설정
- 렌더링된 콘텐츠를 표현
[단점]
- 그대로 innerHTML 프로퍼티에 할당하는것은 XSS에 취약하므로 위험하다.
- 또한 HTML마크업 문자열을 할당하는 경우 , 요소노드의 모든 자식노드를 제거하고 할당한 HTML 마크업 문자열을 파싱한다.
- 새로운 요소를 삽입할때 위치를 지정할 수 없다.
insertAdjacentHTML
- 요소노드를 주어진 위치에 배치
const sayHi = document.querySelector('.sayHi');
sayHi.insertAdjacentHTML('beforebegin', '<span>하나</span>');
sayHi.insertAdjacentHTML('afterbegin', '<span>둘</span>');
sayHi.insertAdjacentHTML('beforeend', '<span>셋</span>');
sayHi.insertAdjacentHTML('afterend', '<span>넷</span>');
위의 코드와 같이 첫번째 인수를 지정해서 사용하면 된다.
지정할 수 있는 인수는 1. beforebegin 2. afterbegin 3.beforeend 4.afterend 이다.
노드 추가 및 생성
요소 노드를 생성
const li = document.createElement('li');
위의 코드는 li노드를 생성하는 코드이다.
생성된 요소 노드는 기존 DOM에 추가되지 않고 홀로 존재하는 상태이다.
텍스트 노드를 생성
const textNode = document.createText("안녕?");
텍스트 노드를 요소 노드의 자식으로 추가
li.appendChild(textNode);
그러면 현자 li와 '안녕?' 이라는 텍스트는 부자관계로 연결만 되어있는 상태이다.
한번에 쓰기
li.appendChild(document.createTextNode('안녕?'))
단 이경우는 요소노드의 자식노드가 있는 채로 할당하면 요소노드의 모든 자식은 제거되고 할당된 텍스트가 추가되므로 주의해야한다.
요소노드를 DOM에 추가
<!DOCTYPE html>
<html lang="ko">
<head>
</head>
<body>
<ul id = "hello">
//여기다 추가 할거임
</ul>
</body>
</html>
[JS]
hello.appendChild(li)
이렇게 하면 hello 요소 노드의자식 요소로 추가된다.
복수 노드 생성 및 추가
여러 개의 요소노드를 생성하여 DOM에 추가하기
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title> </title>
</head>
<body>
<ul class="num"></ul>
<script>
const num = document.querySelector(".num");
["one", "two", "three"].forEach((text) => {
const li = document.createElement("li"); //요소 노드 생성
const textNode = document.createTextNode(text); //textnode생성
li.appendChild(textNode); //텍스트 노드를 자식노드로 넣기
num.appendChild(li); //ul에 자식노드로 li넣기
});
</script>
</body>
</html>
위코드에선 1. 3개요소노드 생성, 2. DOM에 3번 추가 즉, DOM 이 3번 변경된다.
→리플로우, 리페인트 3번실행
Q. 리플로우,리페인트에 대해 알고싶다면?
https://mandelina-code.tistory.com/63
Document.Fragment 사용
- 전 예제에서 보았던 DOM이 자주 변경되는 문제를 Document.Fragment노드를 통해 해결
- Document.Fragment는 별도 서브 DOM을 구성하여 기존 DOM에 추가하기 위한 용도로 사용
- 따라서 Document.Fragment 노드에 자식노드를 추가해도 기존 DOM은 변경사항 X
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title> </title>
</head>
<body>
<ul class="num"></ul>
<script>
const num = document.querySelector(".num");
const fragment = document.createDocumentFragment(); //fragment생성
["one", "two", "three"].forEach((text) => {
const li = document.createElement("li");
const textNode = document.createTextNode(text);
li.appendChild(textNode);
fragment.appendChild(li); // fragment에 자식노드로 li넣기
});
num.appendChild(fragment); // 기존 DOM에 추가
</script>
</body>
</html>
이렇게 하면 DOM변경은 1번 일어나며, 리플로우와 리페인트도 한번 실행
따라서 여러 요소노드를 DOM에 추가하는 경우 Document.Fragment 노드를 사용하는것이 효율적
노드 삽입
1. 마지막 노드로 추가
- Node.prototype.appendChild 사용
- 인수로 전달받은 노드를 자신이 호출한 노드의 마지막 자식요소 DOM에 추가
2. 지정된 위치에 노드 삽입
- Node.prototype.insertBefore(넣을노드,기준노드)
- 기준노드의 앞에 삽입한다.
- 두번째 인수의 노드는 반드시 insertBefore를 호출한 노드의 자식노드여야한다.
num.insertBefore(li,num.lastElementChild);
노드변경
노드이동
- 이미 존재하는 노드를 appendChild 또는 insertBefore 메서드 사용하여 DOM에 다시 추가
- 현재위치에서 노드를 제거하고 새로운 위치에 노드가 추가된다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
</head>
<body>
<ul class="num">
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
<script>
const $num = document.querySelector(".num");
const [$one, $two] = $num.children;
$num.appendChild($one); //one이 마지막 위치로이동
$num.insertBefore($two, lastElementChild); //마지막요소 (three)기준 앞으로 이동
</script>
</body>
</html>
결과는 two - three - one이다.
노드복사
- Node.prototype.cloneNode 이용
- 노드의 사본을 생성하여 반환
- 매개변수 deep에 인수를 전달할 때 true -깊은복사 , false나 생략 : 얕은복사
- 얕은복사로 생성된 요소노드는 자손노드를 복사 x 따라서 텍스트노드는 없다.
const $deepClone = $num.cloneNode (true); //깊은복사
const $shallowClone = $num.cloneNode (false); //얕은복사
노드교체
- Node.prototype.replaceChild (새노드,교체할 노드)
- 자신을 호출한 노드의 자식노드를 다른 노드로 교체
- 교체할 노드는 DOM에서 제거된다.
num.replaceChild(newchild,$num.firstElementChild);
- num요소 노드의 첫 번째 자식 요소를 $newChild 요소 노드로 교체
노드삭제
- Node.prototype.removeChild(삭제할노드) 사용
- 삭제할 노드는 메서드를 호출한 자식 노드여야한다.
$num.removeChild($num.lastElementChild)
- num요소노드의 마지막요소를 DOM에서 삭제
DOM(4) 에선 attribute 조작 및 style조작에 대해 알아보겠다.
https://mandelina-code.tistory.com/58
https://mandelina-code.tistory.com/59
https://mandelina-code.tistory.com/62
https://mandelina-code.tistory.com/66
'FE > JavaScript' 카테고리의 다른 글
DOM(4) - attribute 조작 및 style조작 (0) | 2022.05.22 |
---|---|
[JS] 이벤트 위임 (0) | 2022.05.22 |
[JS] DOM (2) - 노드 탐색 , 및 Text 조작 (0) | 2022.05.18 |
[JS] DOM (1) - DOM이란? (0) | 2022.05.17 |
[JS] JSON (0) | 2022.05.16 |