[바닐라코딩]

[바닐라코딩 | Javascript] - DOM API 요약

개발잘하고싶음 2023. 3. 9. 23:38

1)DOM Introduction

(1)MDN 정의

The Document Object Model (DOM) is a programming interface for HTML.

An application programming interface (API) is a computing interface which defines interactions between multiple software intermediaries.

 

(2)Vanilla Coding

주어진 인터페이스를 이용하여 원하는대로 TV를 조종할 수 있습니다.마찬가지로 DOM이라는 인터페이스를 이용한다면, 자바스크립트를 이용하여 HTML 문서를 조종할 수 있습니다.
 
단, 자바스크립트의 DOM으로 HTML 문서에 접근하고 조종하게 되는 것이 HTML 문서 자체가 수정되는 것은 아니다.

 

2)Selecting Element - HTML 요소를 선택하기

<div class="container">
  <h1>I am a Heading</h1>
  <p>I am a Paragraph</p>
  <ul>
    <li class="item">
      <p>I am a Paragraph</p>
    </li>
    <li class="item">
      <p>I am a Paragraph</p>
    </li>
    <li class="item">
      <p>I am a Paragraph</p>
    </li>
  </ul>
  <button id="special-button">I am a Button</button>
</div>

 

(1)아이디 이름을 이용하여 선택하는 방법

document.getElementById를 이용, HTML 문서 내 고유한 선택자로서 단 하나의 요소가 선택된다. 

// special-button 아이디를 가진 요소를 선택하여 `$el` 변수에 대입
const $el = document.getElementById("special-button");

// special-button 아이디를 가진 요소의 텍스트 변경
$el.textContent = "I am a Special Button";

 

(2)클래스 이름을 이용하여 선택하는 방법

getElementsByClassName 함수를 이용하여 배열과 유사한 형태(유사 배열)로 변수에 할당함. 이 유사 배열에 담긴 각 배열의 요소들이 하나의 HTML Element입니다. 이에 배열의 인덱스를 활용할 수 있음.

// item 클래스를 가진 "모든 요소들"을 선택하여 `$listItems` 변수에 대입
const $listItems = document.getElementsByClassName("item");

// container 클래스를 가진 "모든 요소들"을 선택하여 `$container` 변수에 대입
const $container = document.getElementsByClassName("container");

// getElementsByClassName의 결과값은 배열과 유사한 형태이므로 인덱스로 접근하여 사용한다.
$listItems[0].textContent = "List 1";
$listItems[1].textContent = "List 2";
$listItems[2].textContent = "List 3";

// HTML 상에서 해당 클래스를 가진 요소가 단 하나 뿐이더라도,
// getElementsByClassName의 결과값은 배열과 유사한 형태이므로 인덱스로 접근하여 사용한다.
$container[0].style.backgroundColor = "green";

 

(3)태그 이름을 이용하여 선택하는 방법

getElementsByClassName을 사용한 결과값과 동일한 형태(HTML Element가 담긴 유사 배열)입니다.

// li 태그를 이용한 "모든 요소들"을 선택하여 `$listItems` 변수에 대입
const $listItems = document.getElementsByTagName("li");

// p 태그를 이용한 "모든 요소들"을 선택하여 `$paragraphs` 변수에 대입
const $paragraphs = document.getElementsByTagName("p");

// getElementsByTagName의 결과값은 배열과 유사한 형태이므로 인덱스로 접근하여 사용한다.
$listItems[0].textContent = "List 1";
$listItems[1].textContent = "List 2";
$listItems[2].textContent = "List 3";

// 위치와 상관없이 모든 p 태그를 선택하게 되므로 $paragraphs에는 총 4개의 요소가 선택되고,
// 그 중 첫번째 요소의 배경 색깔을 수정합니다.
$paragraphs[0].style.backgroundColor = "green";

 

(4)CSS 선택자를 이용하여 선택하는 방법

최근에 가장 많이 사용되는 방법입니다. querySelector는 가장 첫 번째 요소를 반환하므로 모든 요소를 유사 배열 형태로 반환하기 위해선 querySelectorAll 사용해야함.

// CSS 선택자 문법을 이용하여 container라는 클래스 이름을 가진 요소를 선택합니다.
// querySelector라는 함수는 모든 경우에 "하나의 요소"를 반환합니다.
const $container = document.querySelector(".container");

const $button = document.querySelector("#special-button");

// 주어진 CSS 선택자와 일치하는 요소가 여러 개일 경우,
// querySelector 함수는 가장 첫번째 요소를 반환합니다.
const $listItem = document.querySelector(".item");

// querySelectorAll 함수는 주어진 CSS 선택자와 일치하는 "모든 요소들"을 유사 배열의 형태로 반환합니다.
// (요소를 제어하고 싶다면 인덱스 위치를 사용해야 합니다.)
const $paragraphs = document.querySelectorAll("p");

 

(5)예시

①textContet Instance properties

Representing the text content of the node and its descendants.

-HTML

<div class="container">
  <p id="first-item">First</p>
  <p>Second</p>
  <p class="third-item">Third</p>
  <p>Fourth</p>
</div>

-JS

const $p1 = document.getElementById("first-item");
const $p2 = document.getElementsByClassName("third-item");

const text1 = $p1.textContent;
const text2 = $p2[0].textContent;

const result = text1 + text2;

if (result === 'FirstThird') {
  alert("🎉");
}

 

textContet Instance properties

-HTML

<div class="container">
  <ul>
    <li>List1</li>
    <li>List2</li>
    <li>List3</li>
  </ul>
  <p>Paragraph1</p>
  <p>Paragraph2</p>
</div>

-JS

const $li = document.getElementsByTagName("li");
const $p = document.getElementsByTagName("p");

const text1 = $li[2].textContent;
const text2 = $p[1].textContent;

const result = text1 + text2;

if (result === 'List3Paragraph2') {
  alert("🎉");
}

 

3)Manipulating Element 

(1)HTML 요소를 수정, 삭제하기

h1 요소의 텍스트를 변경하고자 할 경우 textContent란 속성을 이용하여 h1 요소의 텍스트 내용을 수정할 수 있습니다

const $heading = document.querySelector("h1");
$heading.textContent = "I am a NEW Heading";

 

(2)JS에 CSS 추가하기

①주의사항

속성(property) 관련하여 CSS의 font-size 경우 JS에서 fontSize로 작성해야 함. 아울러  CSS 값(key)은 문자열이므로 " " (따옴표)해야 함.

 

JS에 CSS 추가하기
활용 예시

참고로 아래와 같이 CSS Property 작성시 .fontSize가 아닌 ['font-size']와 같이 대괄호를 통해 할 수도 있다.

⑴HTML

<input
  id="input-text"
  value="hello"
  style="font-size: 1.5em; color: #ff0000; background-color: #e2e2e2;"
/>

⑵JS

const inputNode = document.getElementById("input-text");

// JavaScript에서 지원하는 프로퍼티
console.log(inputNode.style.fontSize);        // 1.5em
console.log(inputNode.style.color);           // rgb(255, 0, 0)
console.log(inputNode.style.backgroundColor); // rgb(226, 226, 226);

// 대괄호 표기법을 사용
console.log(inputNode.style['font-size']);        // 1.5em
console.log(inputNode.style['color']);            // rgb(255, 0, 0)
console.log(inputNode.style['background-color']); // rgb(226, 226, 226)

 

②예시

⑴font-size 등

const itemElement = document.querySelector(".item");

itemElement.style.fontSize="100px";
itemElement.style.color="#55ff00";

⑵background-color 

const rightElement = document.querySelector(".right");
rightElement.style.backgroundColor='yellow'

 

③참고 URL

 

자바스크립트 css 추가하기

자바스크립트에서 css 추가하는 방법을 알아보겠습니다. 바로 코드 복사하실 분은 2번으로 >> 1. 자바스크립트 css 추가 document.getElementById(id).style.property = new style 자바스크립트 css 추가 문법 갑자

ssimplay.tistory.com

 

4)Creating Elements - HTML 요소 생성 및 추가하기

 

(1)개요

수정과 삭제가 가능하듯, 요소를 생성 추가 후 글씨를 수정하고 스타일도 수정할 수 있습니다. 

// h1 요소 만들어서 `heading`이라는 변수에 할당
const heading = document.createElement("h1");

// 방금 생성한 `heading` 요소의 텍스트 설정
heading.textContent = "제목입니당";
// 방금 생성한 `heading` 요소의 스타일 설정
heading.style.fontSize = "50px";

// 방금 생성한 `heading` 요소를 body 태그의 자식으로 추가
document.body.appendChild(heading);

 

(2)변수 선언 위치에 따른 차이

①for문 밖

const something = document.createElement("p");

for (let i = 0; i < 5; i++) {
  something.textContent = i;
  document.body.appendChild(something);
}

// 4만 출력됨.

 

②for문 안

for (let i = 0; i < 5; i++) {
  const something = document.createElement("p");
  something.textContent = i;
  document.body.appendChild(something);
}

//0  1 2 3 4 모두 출력됨 .createElement가 4번 반복되므로.

 

(3)예시

①p 태그 생성 후 textContent 및 body 태그의 자식으로 추가하기

const bodyElement = document.querySelector("body");
const content = document.createElement("p")

content.textContent='I am a paragraph'
bodyElement.appendChild(content);

②ul 태그의 자식요소로서 li 태그 생성 및 추가하기

const ulElement = document.querySelector("ul");
const item = document.createElement("li")
item.textContent = 'second';
ulElement.appendChild(item);

③Todo List 만들기

 

⑴문제

할일 목록을 만드려고 합니다. task를 for문으로 순회하며 각각의 요소를 <li> 태그의 텍스트로 만들어 <ul> 태그의 자식으로 추가해주려고 합니다.최종적으로 Code, Run, Eat, Sleep이 핑크색 화면 안에 나타나도록 코드를 작성해주세요!

 

⑵주어진 자료

-HTML

<div class="wrapper">
  <h1>Todo List</h1>
  <div class="todo-wrapper">
    <ul>
    </ul>
  </div>
</div>

-예시답안

⑶풀이

const task = ["Code", "Run", "Eat", "Sleep"];
const ulElement = document.querySelector("ul");

function listMaker(arr){
  for(let i=0; i<arr.length; i++){
    let list = document.createElement('li');
    list.textContent =task[i];
    ulElement.appendChild(list);
  }
}

listMaker(task);

 

5)Events 

(1)개요

"이벤트"란 웹 상에서 발생하는 사건들을 통칭함.자바스크립트를 이용하여 DOM 요소를 기준으로 이벤트를 감지하고 우리가 원하는 작업을 수행할 수 있습니다.모든 DOM 요소는 addEventListener 메소를 사용할 수 있습니다.

 

①addEventListenewr

addEventListener 메소드는 두 가지 인자를 받았습니다. "click" 문자열과 onButtonClick 함수(Event Handler).

addEventListener는 첫번째 인자로 받은 이벤트가 발생하면(발생한 직후에), 두번째 인자로 받은 함수를 실행합니다.

 

②예시

-HTML

<div>
  <p>아래 버튼을 누르시면 경고창이 날아갑니다!</p>
  <button>경고 1</button>
  <button>경고 2</button>
</div>

-JS

const button = document.querySelector("button");
button.addEventListener("click", function onButtonClick () {
  alert("경고합니다!");
});

 

(2)한 개 이상의 요소에 적용하고자 할 경우

 

위 예제 코드에서는 첫 번째 버튼("경고 1")에 대해서만 클릭 이벤트가 등록되고, 두 번째 버튼은 클릭 이벤트에 대한 처리가 되지 않습니다. 이벤트 등록은 DOM 요소 단위로 이루어지고, 현재 우리는 첫 번째 버튼에 "클릭" 이벤트를 등록해놓았기 때문입니다. 만약 두 가지 버튼 모두 클릭에 대한 처리를 하고 싶었다면 아래와 같이 해야 합니다.

 

①동일한 코드 2 번 작성함

const button1 = document.querySelectorAll("button")[0];
const button2 = document.querySelectorAll("button")[1];

button1.addEventListener("click", function onButtonClick () {
  alert("경고합니다! 버튼 1!");
});

button2.addEventListener("click", function onButtonClick () {
  alert("경고합니다! 버튼 2!");
});

②상위 요소를 객체로 함.

div 요소에 이벤트를 등록함으로써 div 요소의 하위에 존재하는 요소들 모두를 클릭해도 onClick 함수가 실행됩니다. 하지만 문제는 버튼 1과 버튼 2를 구분할 수 없게 되었습니다

const div = document.querySelector("div");

// Event Handler의 매개 변수는 보통 ev 혹은 event라고 이름 짓습니다.
div.addEventListener("click", function onClick (ev) {
  alert("경고합니다!");
});

 

③ Event 객체의 target property 활용함.

Event 등록시 두 번째 인자로써 onClick 함수와 같은 Event Handler에 매개변수를 넣어 사용할 수 있음. 해당 매개변수에는 Event 객체가 오게 되며 해당 객체의 여러 property를 사용할 수 있음. 본 예시에선 이벤트가 발생한 요소를 가리키는 target property를 사용함. 

 

⑴target 속성(property)

"경고 1"을 클릭한다면, ev.target은 첫 번째 버튼 요소가 됩니다. "아래 버튼을 누르시면 경고창이 날아갑니다!"을 클릭한다면, ev.targetp 요소가 됩니다.

 

⑵풀이

const div = document.querySelector("div");
div.addEventListener("click", function onClick (ev) {
  if (ev.target.tagName === "P") {
    return;
  }
  alert("경고합니다! " + ev.target.textContent);
});

 

6)Events Practice

①버튼을 눌렀을 때 <p> 태그의 폰트를 blue 색상이 되도록 이벤트를 등록함.

const buttonElement = document.querySelector("button");
buttonElement.addEventListener("click",function(){
  const pElement = document.querySelector("p");
  pElement.style.color = 'blue';
})