본문 바로가기

개발인생다반사/TIL(Today i learned)

TIL 210806- DOM, 유효성 검사

학습을 시작한지 15일 지났다.

오늘은 돔이다.

이 돔은 아니다.

 

DOM 문서 객체 모델

문서를 객체로?? 웹에서 문서는

브라우저에 표시된 HTML을 언급하는 거니

HTML을 객체 모델로 표시?

 

DOM 시작!

 

DOM : Document Object Model

DOM은 브라우저 환경에서 자바스크립트를 이용해 HTML을 조작할 수 있음

 

Achievement Goals

  • DOM의 개념을 이해할 수 있다.
  • DOM의 구조를 파악하고, HTML과 DOM이 어떻게 닮아있는지 알 수 있다.
  • HTML에서 Javascript 파일을 불러올 때 주의점에 대해서 이해할 수 있다.
    • <script> 태그가 적용되는 위치에 따라서 실행 결과가 달라질 수 있음을 이해할 수 있다.

Advanced Challenge

 

 

HTML에 JavaScript 적용하기

 

지금까지 배웠으면

HTML에서 자바스크립트를 사용하려면

<script>  태그를 이용한다는 것쯤은 알고 있다.

 

웹브라우저가 HTML을 읽다가 script 를 만나면

잠시 멈추고 <script> 요소를 먼저 실행한다.

 

 

script 파일 삽입하는 방법 2가지

1. <head> 태그 안에 삽입하는 방법

2. <body> 태그가 끝나기 전에 삽입하는 방법

 

질문 답:  1번은 HTML로 문서를 읽기 전에

#msg 를 찾으라고 하는데 읽기 전이라서 찾을 수가 없음

 

그래서 우리는 2번을 사용해야 한다.

body 태그가 끝나기 전일 거 같음

 

<html>
  <body>
    <div id="nav">
      <div class="logo"></div>
      <div class="menu-wrapper">
        <div class="menu"></div>
        <div class="menu"></div>
        <div class="menu"></div>
        <div class="profile-photo"></div>
      </div>
    </div>
    <div id="news-contents">
      <div class="news-content-wrapper">
        <div class="news-picture"></div>
        <div class="news-title"></div>
        <div class="news-description"></div>
      </div>
    </div>
    <div id="footer"></div>
  </body>
</html>

 

  • body 엘리먼트의 자식 엘리먼트(element)는 총 몇 개인가요?
  • class의 이름이 news-contents 인 div 엘리먼트의 부모 엘리먼트는 무엇인가요?
  • id의 이름이 nav인 div엘리먼트 를 포함해서, 모든 자식 엘리먼트의 class 이름을 console.log를 사용하여 확인하는 방법을 수도코드(pseudocode)로 작성하세요.

 

Q1 - 자식 엘리먼트 찾기

console.dir(document.body)

body 태그의 자식 엘리먼트 찾음

 

그런데 이것을

console.dir(document.body.chidren) 요렇게 해도 나옴

 

Q2 - 부모 엘리먼트 찾기

자식 엘리먼트 newContents를 따로 선언하여 

id가 newContents인 요소를 할당

 

했더니 나옴 속성 parentElement 사용해서 body 도출

 

 

Q3 - DOM 순회하기

nav의 모든 자식요소를 콘솔로 찍는 함수 의사코드

function consoleLogAllElement(element){
// nav의 class 이름을 console.log 합니다.
// nav의 자식 엘리먼트가 있는지 검색합니다. (logo, menu-wrapper)
  //logo의 class 이름을 console.log 합니다.
  //logo의 자식 엘리먼트가 있는지 검색합니다. (없음)
  //menu-wrapper의 class 이름을 console.log 합니다.
  //menu-wrapper의 자식 엘리먼트가 있는지 검색합니다. (menu, menu, menu, profile-photo)
    //첫 번째 menu의 class 이름을 console.log 합니다.
    //첫 번째 menu의 자식 엘리먼트가 있는지 검색합니다. (없음)
    //두 번째 menu의 class 이름을 console.log 합니다.
    //두 번째 menu의 자식 엘리먼트가 있는지 검색합니다. (없음)
    //세 번째 menu의 class 이름을 console.log 합니다.
    //세 번째 menu의 자식 엘리먼트가 있는지 검색합니다. (없음)
    //profile-photo의 class 이름을 console.log 합니다.
    //profile-photo의 자식 엘리먼트가 있는지 검색합니다 (없음)
 //자식 엘리먼트를 모두 탐색했음으로, 함수 실행이 종료됩니다.
//자식 엘리먼트를 모두 탐색했음으로, 함수 실행이 종료됩니다.
}

 

 

DOM으로 HTML 조작하기

지금 집중할 부분은 CRUD(Create, Read, Update and Delete) 입니다.

이 챕터에서는 document 객체를 통해서

HTML 엘리먼트를 만들고(CREATE),

조회하고(READ), 갱신하고(UPDATE), 삭제하는(DELETE) 하는 방법을 학습

 

Achievement Goals

  • DOM을 JavaScript로 조작하여 HTML Element를 추가하거나 삭제, 혹은 내용을 변경할 수 있다.
    • createElement - CREATE
    • querySelector, querySelectorAll - READ
    • textContent, id, classList, setAttribute - UPDATE
    • remove, removeChild, innerHTML = "" , textContent = "" - DELETE
    • appendChild - APPEND
    • innerHTML과 textContent의 차이

Advanced Challenge

 

CREATE - createElement

document.createElement('div')

[코드] 새로운 div element를 만듭니다.

 

const tweetDiv = document.createElement('div')

[코드] 새롭게 생성한 div element를 변수에 할당합니다.

 

새로운 div 요소는 노드 연결이 안되어 있음

화면에 아무런 변화가 없음

 

 

 

APPEND - append, appendChild

document.body.append(tweetDiv)

append 함수로 변수 tweetDiv를 body에 넣음

 

 

READ - querySelector, querySelectorAll

쉽게 쉽게 빨리 가자. 멈출 수 없다.

const oneTweet = document.querySelector('.tweet')

[코드] querySelector로 클래스 이름이 tweet인 HTML 엘리먼트를 조회합니다.

 

 

const tweets = document.querySelectorAll('.tweet')

[코드] querySelectorAll로 클래스 이름이 tweet 인 모든 HTML 엘리먼트를 유사 배열로 받아옵니다.

 

주의하세요! 앞서 조회한 HTML 엘리먼트들은 배열이 아니다.

이런 '배열 아닌 배열'을 유사 배열, 배열형 객체 등 다양한 이름으로 부른다.

정식 명칭은 Array-like Object 이다.

 

get으로 시작하는 DOM 조회 메소드

const getOneTweet = document.getElementById('container')
const queryOneTweet = document.querySelector('#container')
console.log(getOneTweet === queryOneTweet) // true

[코드] getElementById와 querySelector로 각각 받아 온 container 요소는 하나의 요소입니다.

 

const container = document.querySelector('#container')
const tweetDiv = document.createElement('div')
container.append(tweetDiv)

[코드] tweetDiv를 container의 마지막 자식 요소로 추가합니다.

 

Futher Study

MDN에서 querySelector를 검색하여, 다음의 질문에 대해 학습합니다.

  • querySelector의 첫번째 인자에 'div'를 넣으면 어떻게 될까요?
  • querySelector를 통해서 더 복잡한 작업을 할 수 있을까요?
  • querySelector의 부모는 꼭 document 객체여야만 할까요?

 

UPDATE - textContent, classList.add

console.log(oneDiv) // <div></div>
oneDiv.textContent = 'dev';
console.log(oneDiv) // <div>dev</div>

[코드] textContent를 이용해 문자열을 입력합니다.

 

oneDiv.classList.add('tweet')
console.log(oneDiv) // <div class="tweet">dev</div>

[코드] classList.add를 이용해 'tweet' 클래스를 추가합니다.

 

const container = document.querySelector('#container')
container.append(oneDiv)

[코드] append를 이용해 container의 자식 요소에 oneDiv를 추가합니다.

 

 

MDN에서 setAttribute 라는 메소드를 검색해보세요.

 

 

DELETE - remove, removeChild

 

삭제하려는 엘리먼트의 위치를 알고 있는 경우

const container = document.querySelector('#container')
const tweetDiv = document.createElement('div')
container.append(tweetDiv)
tweetDiv.remove() // 이렇게 append 했던 엘리먼트를 삭제할 수 있다.

[코드] id가 container인 엘리먼트 아래에 tweetDiv를 추가하고, remove로 삭제합니다.

 

 

document.querySelector('#container').innerHTML = '';

[코드] id가 container인 엘리먼트 아래의 모든 엘리먼트를 지웁니다.

 

innerHTML 을 이용하는 방법은 분명 간편하고 편리한 방식이지만, innerHTML은 보안에서 몇 가지 문제를 가지고 있습니다.

 

Element.innerHTML - Web APIs | MDN

The Element property innerHTML gets or sets the HTML or XML markup contained within the element.

developer.mozilla.org

 

const container = document.querySelector('#container');
while (container.firstChild) {
  container.removeChild(container.firstChild);
}

removeChild 는 자식 엘리먼트를 지정해서 삭제하는 메소드입니다. 모든 자식 엘리먼트를 삭제하기 위해, 반복문(while, for, etc.)을 활용할 수 있습니다. 다음의 코드는 자식 엘리먼트가 남아있지 않을 때까지, 첫 번째 자식 엘리먼트를 삭제하는 코드입니다.

 

removeChild 와 while 을 이용해 자식 요소를 삭제하면, 제목에 해당하는 H2 "Tweet List"까지 삭제됩니다. 이를 방지하기 위한 방법은 여러 가지가 있습니다.

 

자식 요소가 담고 있는 문자열을 비교해 "Tweet List"만 남기거나,

새로운 변수를 생성하고 Tweet List를 할당해뒀다가

반복문이 끝난 뒤에 새롭게 추가할 수도 있습니다.

또는 자식 엘리먼트를 하나만 남기게 할 수도 있습니다.

 

const container = document.querySelector('#container');
while (container.children.length > 1) {
  container.removeChild(container.lastChild);
}

[코드] container의 자식 엘리먼트가 1개만 남을 때까지, 마지막 자식 엘리먼트를 제거합니다.

 

 

const tweets = document.querySelectorAll('.tweet')
tweets.forEach(function(tweet){
    tweet.remove();
})
// or
for (let tweet of tweets){
    tweet.remove()
}

[코드] 클래스 이름이 tweet인 엘리먼트만 찾아서 제거합니다.

 

 

Further Study

아래 키워드에 대해서 직접 검색하여 학습하세요.

  • element와 node의 차이 (difference between element and node in javascript dom)
  • children과 childNodes의 차이 (difference between children and childNodes in javascript dom)
  • removeChild와 remove의 차이 (difference between removeChild and remove in javascript dom)
  • tweets에 forEach는 되는데, reduce는 안되는 이유 (why array method is not working on nodelist)
  • tweets를 유사 배열에서 배열로 바꾸는 방법 (how to convert nodelist into javascript array)

시간이 없어 further은 못하겄다.

 

DOM 끝!!

 

유효성 검사 시작!

  • 특정 값은 반드시 입력해야 합니다. (아이디, 이메일, 비밀번호, 이름, 전화번호 등)
  • 비밀번호는 n 자릿수 이상이어야 하고, 숫자나 특수문자를 반드시 포함해야 합니다.
  • 비밀번호와 비밀번호 확인란에 입력된 비밀번호가 동일해야 합니다.
  • 신용카드의 경우, 입력한 신용카드의 번호가 유효해야 합니다.

회원 가입 일정한 조건을 맞춰서 입력했는지 검사하는 것을

유효성 검사(Form validation)라고 한다.

 

 

 

Before You Learn

  • HTML & CSS 기초
  • DOM 기초와 CRUD

Achievement Goals

  • DOM 기초 실습을 통해, 구체적인 사용법을 익힐 수 있다.
    • querySelector를 활용하여, HTML 엘리먼트 정보를 가져올 수 있다.
    • oncilck, onkeyup 속성이나 addEventListener 메소드로 이벤트 핸들러 함수를 HTML 엘리먼트에 적용할 수 있다.
    • 이벤트 핸들러 함수에서 이벤트가 발생한 곳의 정보를 확인할 수 있다.
    • 이벤트 핸들러 함수로 유효성 검사를 실행할 수 있다.
  • 유효성 검사에 필요한 기술 요소를 익힐 수 있다.
    • 유효성 검사에 필요한 HTML 엘리먼트, CSS 속성이 무엇인지 알 수 있다.
      • 엘리먼트가 화면에 표시되거나 사라지게 만들 수 있다. (display: none)
    • 유효성 검사에서 활용할 수 있는 정규표현식 사용법 기초에 대해서 익힐 수 있다. (advanced)
  • 관심사 분리를 적용하거나, 유효성 검사 함수를 따로 분리해서 설계할 수 있다. (advanced)

 

오케이 접수 완료!!

 

이제 페어해서 과제 제출하면 끝!