[TIL] Unit 11. DOM

string_main·2022년 5월 17일
0

JavaScript

목록 보기
5/22
post-thumbnail

🌱 DOM (The Document Object Model)


  • 정의 : 문서 객체 모델(Document Object Model)의 약자로, HTML 요소를 Object(JavaScript Object)처럼 조작(Manipulation)할 수 있는 Model, HTML을 분석하여 HTML의 아주 작은 부분까지 접근할 수 있는 트리 구조

    • DOM을 이용하면 HTML로 구성된 웹 페이지를 동적으로 움직이게 만들 수 있다.

    • DOM은 document 객체에 구현되어 있어 어디에서나 document 객체를 조회할 수 있다.

    console.log(document.body)
    console.dir(document.body)
    ler newsContents = document.body.children[1]

HTML은 프로그래밍을 위해서 만들어진 언어가 아니기 때문에 이전에 배웠던 조건문이나 반복문을 사용할 수 없고, 정보를 저장하기에도 적합한 언어가 아니다. 그래서 JavaScript라는 프로그래밍 언어와 DOM을 활용하여 HTML에 접근하고 조작한다.

🌱 script 태그

  • 웹 브라우저가 작성된 코드를 해석하는 과정에서 <script> 요소를 만나면, 웹 브라우저는 HTML 해석을 잠시 멈춤

🌿 script 추가 방법

  • myScriptFile.js
console.log('welcome JavaScript');

let msgElement = document.querySelector('#msg');
console.log(msgElement);
  1. <head> 안쪽에 삽입하는 방법
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <!-- script 요소 삽입 위치 -->
    <script src="myScriptFile.js"></script>
  </head>
  <body>
    <div id="msg">Hello JavaScript!</div>
  </body>
</html>
Console
------------------
welcome JavaScript 
null
  1. <body> 요소가 끝나기 전 삽입하는 방법
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>
  <body>
    <div id="msg">Hello JavaScript!</div>
    <!-- script 요소 삽입 위치 -->
    <script src="myScriptFile.js"></script>
  </body>
</html>
Console
------------------
welcome JavaScript 
<div id="msg">Hello JavaScript!</div>

두 방식 모두 myScriptFile.js 내의 첫 번째 console.log를 성공적으로 출력하지만, 두 번째 console.log의 경우 첫번째 방법에서는 제대로 출력되지 않는다.

🌱 DOM 조작하기(CRUD)


🌿 CREATE

document.createElement()

const tweetDiv = document.createElement('div');
// tweetDiv라는 요소는 아직 아무런 트리 노드에 연결되어있지 않아 공중부양 중...화면에 변화가 없는 것이 당연함. (APPEND를 해주어야 함)

🌿 APPEND

document.부모요소.append(추가할_자식요소)

document.body.append(tweetDiv);

🌿 READ

  • DOM으로 HTML 엘리먼트의 정보를 조회하기 위해서는 querySelector의 첫 번째 인자로 셀렉터(selector)를 전달하여 확인한다.

  • 셀렉터로는 HTML 요소, id, class 세 가지가 가장 많이 사용

document.querySelector()

const oneTweet = document.querySelector('.tweet') // 클래스명이 tweet인 요소 중 첫번째 요소만 조회
const tweets = document.querySelectorAll('.tweet') // 모든 요소를 조회 (유사 배열, 배열형 객체)

// IE 호환성을 위해 구버전인 getElementById를 사용할 수도 있음.
const getOneTweet = document.getElementById('container')
const queryOneTweet = document.querySelector('#container')
console.log(getOneTweet === queryOneTweet) // true

// 생성한 div요소를 container에 추가
const container = document.querySelector('#container')
const tweetDiv = document.createElement('div')
container.append(tweetDiv)

🌿 UPDATE

요소.textContent = '문자열' : 요소에 문자열 추가
요소.classList.add() : 요소에 클래스 추가
요소.setAttribute('속성명', '속성값') : 지정된 요소의 속성 값 설정

// div요소 생성 및 할당
const oneDiv = document.createElement('div');
console.log(oneDiv) // <div></div>

// 문자열 할당
oneDiv.textContent = 'dev';
console.log(oneDiv) // <div>dev</div>

// CSS 적용을 위한 클래스 추가
oneDiv.classList.add('tweet')
console.log(oneDiv) // <div class="tweet">dev</div>

// container 클래스에 자식 요소 추가
const container = document.querySelector('#container')
container.append(oneDiv)

🌿 DELETE

  1. 요소.remove() : 삭제하려는 요소의 위치를 알고 있는 경우
const container = document.querySelector('#container')
const tweetDiv = document.createElement('div')
container.append(tweetDiv)
tweetDiv.remove() // 이렇게 append 했던 요소를 삭제할 수 있다.
  1. innerHTML = ''; : 여러 개의 자식 요소를 지우기
document.querySelector('#container').innerHTML = '';

innerHTML 사용은 꼭 필요하지 않으면 지양하는 것이 좋다. HTML tag를 직접 삽입하여 실행하는 형태의 메서드는 <script> 를 활용하여 강제로 해커가 원하는 스크립트를 실행시키는 XSS Attack이 대표적인 위험성이다.

  1. removeChild : 자식 요소를 지정해서 삭제하는 메서드 (innerHTML의 보안 문제를 보완할 좋은 방법)
// 자식 요소가 남아있지 않을 때 까지 첫번째 자식 요소 삭제
const container = document.querySelector('#container');
while (container.firstChild) {
  container.removeChild(container.firstChild);
}

// 마지막 요소만 남기는 방법
const container = document.querySelector('#container');
while (container.children.length > 1) {
  container.removeChild(container.lastChild);
}

// 클래스 이름을 찾아 삭제하는 방법
const tweets = document.querySelectorAll('.tweet')
tweets.forEach(function(tweet){
    tweet.remove();
})
// or
for (let tweet of tweets){
    tweet.remove()
}

🌱 유효성 검사 (Form validation)


  • 정의 : 요청한 데이터가 어떤 조건에 충족하는지 확인하는 작업 (ex. 비밀번호 n자리 이상 입력, 특수문자 및 숫자 포함)

  • DOM으로 <input type="text"> 또는 <textarea>와 같은 엘리먼트의 입력 값을 설정하거나, 얻어내려면 .value 속성을 사용한다.

document.querySelector('#username').value

// 버튼을 클릭하면 출력되게 하는 이벤트 리스너
// 방법 1 : DOM 객체에 onclick을 직접 지정
btn.onclick = function() {
  console.log('버튼이 눌렸습니다!');
}

// 방법 2 : addEventListener 메서드 사용하여 함수 할당
btn.addEventListener('click', function() {
  console.log('버튼이 눌렸습니다!');
});

// 방법 3
function handler() {
  console.log('버튼이 눌렸습니다!');
}

btn.onclick = handler;

🌱 이벤트 객체


  • POS기 프로그램
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>이벤트 객체</title>
  </head>
  <body>
    <button>아메리카노</button>
    <button>카페라떼</button>
    <script>
      let menus = document.querySelectorAll("button"); //모든 버튼을 가져옵니다.

      let btnAmericano = menus[0];
      let btnCaffelatte = menus[1];

      function handleClick() {
        // 아래의 빈 칸(____)을 채우세요.
        // console.log("working?");
        let currentMenu = event.target.innerText; // TODO
        console.log(currentMenu + "를 클릭하셨습니다.");
      }

      btnAmericano.onclick = handleClick;
      btnCaffelatte.onclick = handleClick; // 이상으로 for 문으로 충분히 구현할 수 있는 내용입니다.
    </script>
  </body>
</html>

🌱 알게된 것


  • DOM을 활용하면 HTML을 조작할 수 있다.
  • node는 요소의 상위 개념이다.
  • HTML 구조가 JavaScript의 객체 구조와 같은 트리 구조여서 다른 언어도 DOM을 가지고 있지만, JS의 DOM이 브라우저에 접근하기 바람직하다.
  • 같은 요소를 appendChild 하면, 기존 요소를 복사하는 것이 아닌 이동이다.
  • 좌표 정보 조회 - offsetTop
  • 레이아웃 너비 정보 조회 - offsetWidth
  • 기본 동작 방지 - event.preventDefault
  • querySelector의 부모는 document 하위의 어떤 객체든 자식 엘리먼트를 가지고 있다면 부모가 될 수 있다.

🌱 추가 학습


  • DOM과 JavaScript의 차이
  • 이벤트 리스너 정의 방법
  • 요소와 노드의 차이
  • 이벤트 객체
  • createDocumentFragment
  • children과 childNodes 차이
  • remove와 removeChild의 차이
  • innerText와 textContent의 차이
  • importNode와 cloneNode
  • appendChild와 prependChild
  • insertBefore와 insertAfter

| 참고 자료 |

profile
FE developer

0개의 댓글