DOM

현성·2023년 12월 5일
0

DOM (Document Object Model) 이란 ?

  • DOM이란 HTML문서를 객체로 표현한 것으로, JS에서 HTML을 제어할 수 있게 해줍니다.
  • 이때 사용하는 명령들을 DOM API라고 합니다.
const element = document.querySelector("h1");
console.log(element.textContent);

Node vs Element

  • Node : HTML 요소, 텍스트, 주석 등 모든 것을 의미합니다.
  • Element : HTML 요소를 의미합니다.

  • html
<body>
  <div class="parent">
    <!-- 주석 -->
    <div class="child">1</div>
    텍스트1
    <div class="child">2</div>
    텍스트2
  </div>
</body>
  • js
const parent = document.querySelector(".parent");

// 부모 요소의 모든 자식 노드 확인 !
console.log(parent.childNodes);

// 부모 요소의 모든 자식 요소 확인 !
console.log(parent.children);

검색과 탐색

document.getElementById()

  • HTML id 속성(Attributes) 값으로 검색한 요소를 반환합니다.
  • 여러 요소가 검색되면, 가장 먼저 찾은 요소만 반환합니다.
  • 검색 결과가 없으면, null을 반환합니다.

html

<body>
  <div class="parent">
    <!-- 주석 -->
    <div class="child">1</div>
    텍스트1
    <div id="child2" class="child">2</div>
    텍스트2
  </div>
</body>

main.js

const el = document.getElementById('child2')
console.log(el) // <div id="child2" class="child">2</div>
const el = document.getElementById('child')
console.log(el) // null

document.querySelector()

  • 'CSS 선택자'로 검색한 요소를 하나 반환합니다.
  • 여러 요소가 검색되면, 가장 먼저 찾은 요소만 반환합니다.
  • 검색 결과가 없으면, null을 반환합니다.
const el = document.querySelector(".child:first-child");
console.log(el); // <div class="child">1</div>

document.querySelectorAll()

  • 'CSS 선택자'로 검색한 모든 요소를 NodeList로 반환합니다.
  • NodeList객체는 forEach()를 사용할 수 있습니다.
const nodeList = document.querySelectorAll(".child");
console.log(nodeList);
nodeList.forEach((el) => console.log(el.textContent)); // 1 2

// Array.from메소드를 통해 유사배열을 배열로 바꿀 수 있습니다.
console.log(Array.from(nodeList).reverse());

N.parentElement()

  • 노드의 부모 요소를 반환합니다.
const el = document.querySelector(".child");
console.log(el.parentElement); // <div class="parent">…</div>

E.closest()

  • 자신을 포함한 조상 요소 중 'CSS 선택자'와 일치하는 가장 가까운 요소를 반환합니다.
  • 요소를 찾지 못하면 null을 반환합니다.
const el = document.querySelector(".child");

console.log(el.closest("div")); // <div class="child">1</div>
console.log(el.closest("body")); // <body>...</body>
console.log(el.closest(".hello")); // null

N.previousSibling / N.nextSibling

  • 노드의 이전 형제 혹은 다음 형제 노드를 반환합니다.
const el = document.querySelector(".child");

console.log(el.previousSibling); // #text
console.log(el.nextSibling); // 텍스트1

N.previousElementSibling / N.nextElementSibling

  • 노드의 이전 형제 혹은 다음 형제 요소를 반환합니다.
const el = document.querySelector(".child");

console.log(el.previousElementSibling); // null
console.log(el.nextElementSibling); // <div id="child2" class="child">2</div>

E.children

  • 요소의 모든 자식 요소를 반환합니다.
const el = document.querySelector(".parent");

// 유사 배열(HTMLCollection)
console.log(el.children);

// 배열
console.log(Array.from(el.children));

E.firstElementChild / E.lastElementChild

  • 요소의 첫 번째 자식 혹은 마지막 자식 요소를 반환합니다.
const el = document.querySelector(".parent");

console.log(el.firstElementChild);
console.log(el.lastElementChild);

생성, 조회, 수정

html

<body>
  <div class="parent">
    <div class="child">1</div>
    <div class="child">2</div>
  </div>
</body>

document.createElement()

  • 메모리에만 존재하는 새로운 HTML 요소를 생성해 반환합니다.
const divEl = document.createElement("div");
console.log(divEl);

const inputEl = document.createElement("input");
console.log(inputEl);

E.prepend() / E.append()

  • 노드를 요소의 첫 번째 혹은 마지막 자식으로 삽입합니다.
const parentEl = document.querySelector(".parent");

const el = document.createElement("div");
el.textContent = "Hello~";

parentEl.prepend(new Comment(" 주석 "));

// append메소드는 여러 번 호출할 필요 없이 인수의 순서대로 동작합니다.
parentEl.append(el, "Text!");

html 결과

<body>
  <div class="parent">
    <!-- 주석 -->
    <div class="child">1</div>
    <div class="child">2</div>
    <div>Hello~</div>
    "Text!"
  </div>
</body>

E.remove()

  • 요소를 제거합니다.
const el = document.querySelector(".child");

el.remove();

html 결과

<body>
  <div class="parent">
    <div class="child">2</div>
  </div>
</body>

E.insertAdjacentElement()

  • '대상 요소'의 지정한 위치에 '새로운 요소'를 삽입합니다.
  • 대상_요소.insertAdjacentElement(위치, 새로운_요소)

html에서 위치 확인

<body>
  <div class="parent">
    <!-- 'beforebegin' -->
    <div class="child">
      <!-- 'afterbegin' -->
      1
      <!-- 'beforeend' -->
    </div>
    <!-- 'afterend' -->
    <div class="child">2</div>
  </div>
</body>
const childEl = document.querySelector(".child");
const newEl = document.createElement("span");
newEl.textContent = "Hello~";

childEl.insertAdjacentElement("beforebegin", newEl);

N.insertBefore()

  • '부모 노드'의 자식인 '참조 노드'의 이전 형제로 '노드'를 삽입합니다.
  • 부모_노드.insertBefore(노드, 참조_노드)
const parentEl = document.querySelector(".parent");
const childEl = document.querySelector(".child");
const newEl = document.createElement("span");
newEl.textContent = "Hello~";

parentEl.insertBefore(newEl, childEl);

HTML 결과

<body>
  <div class="parent">
    <span>Hello~</span>
    <div class="child">1</div>
    <div class="child">2</div>
  </div>
</body>

N.contains()

  • '주어진 노드'가 '노드'의 자신을 포함한 후손인지 확인합니다.
  • 노드.contains(주어진_노드)
const parentEl = document.querySelector(".parent");
const childEl = document.querySelector(".child");

console.log(parentEl.contains(childEl)); // true
console.log(document.body.contains(parentEl)); // true
console.log(document.body.contains(childEl)); // true
console.log(document.body.contains(document.body)); // true
console.log(parentEl.contains(parentEl)); // true
console.log(parentEl.contains(document.body)); // false
console.log(childEl.contains(document.body)); // false

N.textContent

  • 노드의 모든 텍스트를 얻거나 변경합니다.
const el = document.querySelector(".child");
console.log(el.textContent); // 1

el.textContent = 7;
console.log(el.textContent); // 7

E.innerHTML

  • 요소의 모든 HTML 내용을 하나의 문자로 얻거나, 새로운 HTML을 지정합니다.

html

<body>
  <div class="parent">
    <div class="child">1</div>
    <div class="child">2</div>
  </div>
</body>
const el = document.querySelector(".parent");
console.log(el.innerHTML);
// <div class="child">1</div>
// <div class="child">2</div>
  • 화면 출력


const el = document.querySelector(".parent");

el.innerHTML = /* html */ `
<div style="border: 4px solid;">
  <span style='color: red;'>hello</span>
  <span style='color: red;'>hello</span>
</div>
`;
  • 화면 출력


E.dataset

  • 요소의 각 data- 속성 값을 얻거나 지정합니다.
const el = document.querySelector(".child");
const str = "Hello world!";
const obj = { a: 1, b: 2 };

el.dataset.helloWorld = str;
el.dataset.object = JSON.stringify(obj);

console.log(el.dataset.helloWorld);
console.log(el.dataset.object);
console.log(JSON.parse(el.dataset.object));

E.tagName

  • 요소의 태그 이름을 반환합니다.
const parentEl = document.querySelector(".parent");
const childEl = document.querySelector(".child");
const el = document.createElement("span");

console.log(parentEl.tagName); // DIV
console.log(childEl.tagName); // DIV
console.log(el.tagName); // SPAN
console.log(document.body.tagName); // BODY

E.id

  • 요소의 id 속성 값을 얻거나 지정합니다.
const el = document.querySelector(".child");
console.log(el.id); // ""

el.id = "child1";
console.log(el.id); // child1
console.log(el); // <div class="child" id="child1">1</div>

E.className

  • 요소의 class 속성 값을 얻거나 지정합니다.
const el = document.querySelector(".child");
console.log(el.className); // child

el.className += " child1 active";
console.log(el.className); // child child1 active
console.log(el); // <div class="child child1 active">1</div>

E.classList

  • 요소의 class 속성 값을 제어합니다.
  • .add() : 새로운 값을 추가합니다.
  • .remove() : 기존 값을 제거합니다.
  • .toggle() : 값을 토글합니다.
  • .contains() : 값을 확인합니다.
const el = document.querySelector(".child");

el.classList.add("active");
console.log(el.classList.contains("active")); // true

el.classList.remove("active");
console.log(el.classList.contains("active")); // false

el.addEventListener("click", () => {
  el.classList.toggle("active");
  console.log(el.classList.contains("active"));
});

E.style

  • 요소의 style 속성(인라인 스타일)의 CSS 속성 값을 얻거나 지정합니다.
const el = document.querySelector(".child");

// 개별 지정 !
// el.style.width = "100px";
// el.style.fontSize = "20px";
// el.style.backgroundColor = "green";
// el.style.position = "absolute";

// 한 번에 지정 !
Object.assign(el.style, {
  width: "100px",
  fontSize: "20px",
  backgroundColor: "green",
  position: "absolute",
});

console.log(el.style);
console.log(el.style.width); // 100px
console.log(el.style.fontSize); // 20px
console.log(el.style.backgroundColor); // green
console.log(el.style.position); // absolute

window.getComputedStyle()

  • 요소에 적용된 스타일 객체를 반환합니다.
  • E.style은 인라인 작성방식으로 적용된 내용만 반환하는데 반해, window.getComputedStyle()은 실제로 요소에 적용된 CSS 내용을 반환합니다.
const el = document.querySelector(".child");
const styles = window.getComputedStyle(el);

console.log(styles.width);
console.log(styles.fontSize);
console.log(styles.backgroundColor);
console.log(styles.position);

E.getAttribute() / E.setAttribute()

  • 요소에서 특정 속성 값을 얻거나 지정합니다.
const el = document.querySelector(".child");

el.setAttribute("title", "Hello World!");
console.log(el); // <div class="child" title="Hello World!">1</div>
console.log(el.getAttribute("title")); // Hello World!

E.hasAttribute() / E.removeAttribute()

  • 요소에서 특정 속성을 확인하거나 제거합니다.
const el = document.querySelector(".child");

console.log(el.hasAttribute("class")); // true

el.removeAttribute("class");
console.log(el.hasAttribute("class")); // false

console.log(el); // <div>1</div>

크기와 좌표

window.innerWidth / window.innerHeight

  • 현재 화면(Viewport)의 크기를 얻습니다.
<body>
  <div class="parent">
    <div class="child">1</div>
    <div class="child">2</div>
  </div>
</body>
body {
  height: 1000px;
  padding: 500px 0;
}

.parent {
  width: 300px;
  height: 200px;
  margin-top: 1000px;
  padding: 20px;
  overflow: auto;
  border: 10px solid;
}

.child {
  height: 100px;
  margin-top: 100px;
  border: 10px solid red;
}
console.log(window.innerWidth);
console.log(window.innerHeight);

window.scrollX / window.scrollY

  • 페이지의 좌상단 기준, 현재 화면(Viewport)의 수평 혹은 수직 스크롤 위치를 얻습니다.
console.log(window.scrollX, window.scrollY);

window.scrollTo() / E.scrollTo()

  • 지정된 좌표로 대상(화면, 스크롤 요소)을 스크롤합니다.
  • 대상.scrollTo(X좌표, Y좌표)
  • 대상.scrollTo({ top: Y, left: X, behavior: 'smooth'})
setTimeout(() => {
  window.scrollTo(0, 500);
}, 1000);

// 작성한 좌표로의 이동이 부드럽게 작동합니다.
setTimeout(() => {
  window.scrollTo({ top: 1000, left: 0, behavior: "smooth" });
}, 2000);

  • 요소에서 적용
const parentEl = document.querySelector(".parent");

setTimeout(() => {
  parentEl.scrollTo({ top: 200, left: 0, behavior: "smooth" });
}, 1000);

E.clientWidth / E.clientHeight

  • 테두리 선(border)을 제외한 요소의 크기를 얻습니다.
const parentEl = document.querySelector(".parent");
const childEl = document.querySelector(".child");

console.log(parentEl.clientWidth, parentEl.clientHeight); // 340 200
console.log(childEl.clientWidth, childEl.clientHeight); // 280 100

E.offsetWidth / E.offsetHeight

  • 테두리 선(border)을 포함한 요소의 크기를 얻습니다.
const parentEl = document.querySelector(".parent");
const childEl = document.querySelector(".child");

console.log(parentEl.offsetWidth, parentEl.offsetHeight); // 360 260
console.log(childEl.offsetWidth, childEl.offsetHeight); // 300 120

E.scrollLeft / E.scrollTop

  • 스크롤 요소의 좌상단 기준
  • 현재 스크롤 요소의 수평 혹은 수직 스크롤 위치를 얻습니다.
window.parentEl = document.querySelector(".parent");

console.log(parentEl.scrollLeft, parentEl.scrollTop);

E.offsetLeft / E.offsetTop

  • 페이지의 좌상단 기준, 요소의 위치를 얻습니다.
const parentEl = document.querySelector(".parent");
const childEl = document.querySelector(".child");

console.log(parentEl.offsetLeft, parentEl.offsetTop);
console.log(childEl.offsetLeft, childEl.offsetTop);

E.getBoundingClientRect()

  • 테두리 선(border)을 포함한 요소의 크기와 화면에서의 상대 위치 정보를 얻습니다.
const parentEl = document.querySelector(".parent");
const childEl = document.querySelector(".child");

console.log(parentEl.getBoundingClientRect());
console.log(childEl.getBoundingClientRect());
profile
👈🏻 매일 꾸준히 성장하는 개발자 !

0개의 댓글