DOM
DOM을 이전 비트컴퓨터 교육 때 배웠을 때는 이해도 안되고 어려웠던 걸, 차분히 개념부터 사용법까지 읽어보니 그당시 같이 공부하던 친구들이 별거없다고 한게 기억난다. 이글은 DOM에 대해 아무것도 모를때 뭘써야될지 몰라서 비워놨다 내용을 본 후 적는거라 개념이 잡혔다. 이전에는 3개월안에 Java, JavaScript, JQUERY, Oracle, SQL 등 너무 병행하다보니, SQL의 CRUD와 DOM의 CRUD가 헷갈렸었는데 완전히 다른거란걸 알고 쓰니 마음이 편하다. 헷갈리는 당신 한번 보시고 DOM은 꽤나 봐야될게 많은 듯 reference역시 만만치 않다. 궁금할때 검색창에 치는것도 좋지만, 글에 남겨진 ref만 참고하더라도 왠만한건 해결가능하다.
1. DOM이란?
Document Object Model의 약자로 HTML 요소를 Object(JS의 객체)처럼 조작(Manipulation)할 수 있는 model이다. JS를 통해 DOM을 통해 HTML을 객체로 조작할 수 있다.
2. <script>
의 이해
HTML parsing 중 <script>
태그를 만나면 HTML parsing paused되면서 Script fetch, Script execution을 거친다.
2.1. 적용법
<!DOCTYPE html>
<html lang="en">
<head>
...
<!-- 방법1 head에 추가 -->
<script scr="addHead.js"></script>
</head>
<body>
<div id="msg">Hello World</div>
<!-- 방법2 body맨 끝줄에 추가 -->
<script scr="addBody.js"></script>
</body>
</html>
2.2. 차이
// add(Head or Body).js 파일
console.log("this is first line in js file");
const msgTag = document.querySelector("#msg");
console.log(msgTag);
상기 방식으로 head와 body를 추가하였을 때 body맨 끝줄에 추가된 script 태그는 정상적으로 div태그를 불러오지만, head에 추가된 script 태그는 div 태그를 불러오지 못한다. android의 lifeCycle처럼 HTML parsing이 끝난 후 script 태그가 생성되야 제대로 동작한다.
3. console.dir(CONTENTS);
//단순 출력
console.log('just print');
//()내 지정된 계층구조 출력
console.dir(document.body.children);
//해당구문으로는 객체를 불러오지 부모객체 접근하지 못함.
console.dir(document.getElementById.???)
//최신브라우저에서 querySelector사용
console.dir(document.querySelector('div#id').parentElement);
console.dir에 내장된 기능에 따라 콘솔창을 이용하여 계층구조를 파악할 수 있다.
4. DOM CRUD
document객체에는 많은 속성과 메서드가 존재한다. 하지만 가장 우선적인건 CRUD이다. CRUD한 다음 HTML에 적용할 시 APPEND하는 것 주의.
4.1. querySelector
Query는 ~를 조회한다. 쿼리를 날리다 같은 jargon(특정 영역 사용 단어)의 뜻을 가진다.
- querySelector(content): content인 HTML element 중 첫번째 element 조회
- querySelectorAll(content): content인 HTML element의 모든 요소를 배열같은 객체(for구문 사용가능)로 가져온다. => 유사배열으로 배열이 아니다. Array like Object
- 브라우저에 따라서 호환성을 고려해야한다.
DOM CRUD 내 코드박스 확인
4.2. CREATE READ UPDATE DELETE
//======CREATE
const newDiv = document.createElement("div");
//------아직 append하지않음.
document.body.append(newDiv);
//------chrome inspect element 탭에서 확인가능
//======READ
/* 원시형은 직접조회,
참조 자료형 중 배열은 index, 객체는 key,
DOM은 HTML Element 정보 조회시 querySelector 1번째 인자로 Selector 전달
HTML: "tag"
id: "#id"
class: .class
*/
//------querySelector 호환성
//------브라우저가 이전버전이라 호환성을 고려해야한다면 이전 syntax사용
document.getElementById("target") === document.querySelector("#target"); //true
//------READ 후 CREATE
const target = document.querySelector("#target");
const newDiv = document.createElement("div");
target.append(newDiv);
//======UPDATE
const updateDiv = document.createElement("div");
updateDiv.textContent = "some update content"; //문자열 입력
updateDiv.classList.add("update"); //class 추가
target.append(updateDiv);
//======DELETE
const target = document.querySelector("#target");
updateDiv.remove(); //append요소 삭제
document.querySelector("target").innerHTML = "";
//------target내 자식요소 모두 삭제
//------보안 문제점있음 참조 내 MDN:WebAPI/innerHTML 확인
//------removeChild이용
while (target.fistChild) {
//부모 내 첫번째 자식이 있을때
//없으면 false로 반복문 빠져나옴.
target.removeChild(container.firstChild);
}
//------선택적 삭제
//------비교하여 넘기거나, 다 삭제 후 추가 원하는대로 구현가능
//------한개 남을때까지 뒤에서부터 지워주세요
while (target.children.length > 1) {
target.removeChild(container.lastChild);
}
//------class 사용 선택 삭제
const classChilds = document.querySelectorAll(".child");
classChilds.forEach(function (child) {
child.remove();
});
for (let child of classChilds) {
child.remove();
}
참조
StackOverflow:Q/JSgetParentElementBySelector
MDN:WebAPI/DOM
MDN:WebAPI/Node
MDN:WebAPI/Element
MDN:WebAPI/Node/parentElement
MDN:WebAPI/Element/innerHTML
MDN:WebAPI/Element/innerText
MDN:WebAPI/Node/textContent
MDN:WebAPI/Element/setAttribute
MDN:WebAPI/createDocumentFragment
MDN:HTML/template
꿀벌개발일지:엘리멘터와 노드의 차이
KO.JS.Info/DOM 컬렉션
MDN:WebAPI/Node/removeChild
MDN:WebAPI/Element/remove
Indepth.dev:appendChildMovesADomNodeBetweenParents
MDN:WebAPI/Element/offsetTop
MDN:WebAPI/Element/offsetWidth