코드스테이츠_4주차_화,수

윤뿔소·2022년 9월 13일
0

CodeStates

목록 보기
14/47
post-thumbnail

오늘은 배웠던 JS로 HTML를 제어하는 방법을 터득할 것이다!

DOM의 정의

  • DOM의 개념을 이해한다.
  • DOM의 구조를 파악하고, HTML과 DOM이 어떻게 닮아있는지 이해한다.
  • HTML에서 JavaScript 파일을 불러올 때 주의점에 대해서 이해한다.
  • DOM과 JavaScript의 차이에 대해 이해할 수 있다.
  • Document Object Model
  • HTML 요소를 JS Object처럼 조작(Manipulation)할 수 있는 Model
    즉 JS로 HTML을 조작하기!
  • DOM이라는 규칙을 통해 브라우저는 렌더링, 웹 구현

DOM 특징

렌더링 순서

  • 우선 HTML에서 <script>라는 태그로 스크립팅 언어(JS, DOM)을 불러옴
  • 브라우저가 HTML에서 이 요소를 읽으면 HTML 해석을 중단하고 먼저 이 스크립트를 해석(Parsing)함
  • ⭐️그래서 JS 파일을 불러오는 <script>를 '어디에 써주는 가'가 중요함
  • defer 써주면 되긴 함;;

조회 및 반환

  • console.dir(document.El) : 해당 태그(요소), ID, Class를 불러와 콘솔창에 띄우는 것! 객체 데이터를 불러오는 거에서 착안
  • 배열 데이터 반환, 정확히는 배열과 비슷한 걸 반환
  • 이 이미지는 결괏값을 보여줌, 아래 Children에 자식 요소 있음
  • 아래 요소를 더 불러오고 싶으면 배열로서 불러와야함, 자주 봐야한다면 변수 지정

의사 코드(Pseudo Code)

JS든 DOM이든 부모 요소 안 자식 요소 안 그 자식요소...의 구조를 띔, 즉 트리 구조이므로 구조를 파악, 쭉 써가면 됨

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 다루기(CARUD)

  • DOM을 JavaScript로 조작해 HTML Element를 추가, 조회, 변경, 삭제할 수 있음
  • 생성한 HTML Element를 부모 엘리먼트의 자식 엘리먼트로 포함할 수 있다. (APPEND)
  • innerHTMLtextContent의 차이를 이해한다.
  • DOM과 JS의 차이에 대해 이해할 수 있다.
  • createDocumentFragment를 활용하여, 더 효율적으로 DOM을 제어
  • HTML5 template tag 사용법을 이해
  • elementnode의 차이를 이해
  • childrenchildNodes의 차이를 이해
  • removeremoveChild의 차이를 이해
  • 같은 엘리먼트를 appendChild하면, 기존 엘리먼트를 복사할까?
  • offsetTop 등을 이용하여 좌표 정보를 조회
  • offsetWidth 등을 이용하여 크기 정보를 조회

JS 같은 스크립팅 언어로 HTML을 조작해보자!
element = document.~

Create

요소를 만듦, 만들기만 해서 옮겨줘야함

let Vari = document.createElement('요소')

Append

  • 요소를 자식으로 옮겨줌, 보통 Create하고 그 변수를 append붙여 옮김
  • body가 아닌 그 하위 요소라면 새로 변수에 그 경로를 넣어 해줘야함
  • 요소가 들어가있는 변수말고 따옴표로 감싼다면 문자열도 가능

    `document.body.append(Vari)

궁금증

궁금함 더 쉬운 방법이 뭐지?

생성한 tweetDiv 를 container 에 넣기 위해서는, container 를 먼저 찾아야 합니다. 어떻게 container 를 찾을 수 있을까요? 위에서 언급했던 DOM 트리를 순회해서 찾을 수 있습니다. 그러나 보다 더 편리한 방법이 있으니 검색해 보시기 바랍니다.

Read

  • 잔존하는 HTML 요소 자체를 조회함, 조회해서 수정이나 옮기기 가능
  1. querySelector(), querySelectorAll()
    .이나#으로 Class, Id를 불러올 수 있음
  2. getElementById(), getElementsByClassName()
    Id에는 Id만 ClassName에는 Class만 불러올 수 있음
  • 1번: 편함, 구체적, 클래스와 아이디 다중 선택 가능(Cl1, Cl2 ...), NodeList로 반환, All은 유사 배열로 반환(반복이나 인덱스 참조만 가능, Array 메소드 사용 불가)
    단점: 성능 떨어짐, 느림, IE8부터 호환
  • 2번: 빠름, 특정성, 모든 브라우저 호환, HTMLCollection으로 반환, Class 유사 배열 반환
    단점: class쓰려면 따로 해줘야함, 불편
    즉! 빠르게 처리해야하거나 중요한 ID라면 getElementById()를 쓰고 클래스나 다른 선택자를 쓰고 싶음 querySelector()를 쓰자

+ NodeListHTMLCollection 복습 필수!

Update

만들었던, 가져왔던 변수(요소)들을 이제 수정해보자

  • element.textContent = "내용" : 요소의 Value(내용) 수정
  • ⭐️element.classList.add("Class") : 요소에 클래스 추가(多)
  • element.setAttribute('attributename', 'attributevalue'): 요소에 속성 추가(placeholder, title 등)

Delete

  • element.remove() : 저장했던 요소의 변수를 입력해 없애버림!
  • element.innerHTML로 다중으로 삭제 가능하지만 보안상 안씀, 쓰지 않는 걸 권장, 그래서 querySelectorAll() + forEachwhile로 반복해 전체 삭제를 해주면 됨
// 자식을 while로 삭제
const container = document.querySelector('#container');
while (container.children.length > 1) { // 하나빼고 모든 자식 삭제
  container.removeChild(container.lastChild);
}
// 그 자식인 .tweet을 직접적으로 삭제
const tweets = document.querySelectorAll('.tweet')
tweets.forEach(function(tweet){
    tweet.remove();
})

페어 과제

과제로 '유효성 검사'의 최소한의 기능을 구현함

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

참고 : HTML

<body>
    <main>
      <img class="logo" src="./images/codestates-logo.png" alt="CODE_STATES_LOGO" />

      <fieldset>
        <input type="text" id="username" placeholder="아이디" />
      </fieldset>
      <!-- 클래스 2개 설정, 띄어쓰기 -->
      <div class="success-message hide">사용할 수 있는 아이디입니다.</div>
      <div class="failure-message hide">아이디는 네 글자 이상이어야 합니다.</div>

      <fieldset>
        <input type="password" id="password" placeholder="비밀번호" />
      </fieldset>

      <fieldset>
        <input type="password" id="password-retype" placeholder="비밀번호 확인" />
      </fieldset>

      <div class="mismatch-message hide">비밀번호가 일치하지 않습니다.</div>

      <fieldset class="signup">
        <button type="button" class="signup-button">회원가입</button>
      </fieldset>

      <script src="./script.js"></script>
    </main>

1. Document에서 공통 변수 가져오기

let elInputUsername = document.getElementById("username");
let elFailureMassage = document.querySelector(".failure-message");
let elSuccessMassage = document.querySelector(".success-message");
let elPassword1 = document.getElementById("password");
let elPassword2 = document.getElementById("password-retype");
let elMismachMessage = document.querySelector(".mismatch-message");
let signButton = document.querySelector(".signup-button");

2. ID 메세지 출력

  1. 키보드를 누르고 떼면 메세지가 출력(HTML)
  2. 4글자를 기준으로 미만이면 실패, 이상이면 성공
// ID 성공 메세지 출력, 실패 메세지 가림
function isMoreThan4Length(value) {
  // return과 비교연산자로 불린데이터 반환하는 함수 제작
  return value.length >= 4;
}
// DOM의 프로퍼티로 추가하는 거면 on+이벤트를 붙여 메소드처럼 사용 가능
elInputUsername.onkeyup = function () {
  if (isMoreThan4Length(elInputUsername.value)) {
    elSuccessMassage.classList.remove("hide");
    elFailureMassage.classList.add("hide");
  } else {
    elSuccessMassage.classList.add("hide");
    elFailureMassage.classList.remove("hide");
  }
};

+ keyup은 JS에 내장돼 있는 '이벤트'임, 사이트 들어가서 이런 게 있구나 하고 함 보기

3. 유효성 검사: 조건에 해당?

// 유효성 검사
function isMatch(password1, password2) {
  return password1 === password2;
}
// elPassword2.addEventListner("keyup", () => {}): 리스너
elPassword2.onkeyup = function () { // 핸들러
  // value 중요!
  if (isMatch(elPassword1.value, elPassword2.value)) {
    elMismachMessage.classList.add("hide");
  } else {
    elMismachMessage.classList.remove("hide");
  }
};

여기서 포인트는 요소에 .value를 붙여 요소 자체가 아닌 그 값, 내용을 isMatch의 파라미터로 지정했음! 그 차이를 알아야함

이벤트 객체

  • 기초적인 event를 알고, event handler를 element에 적용할 수 있다.
  • onclick에 직접 할당하는 것과 addEventListener의 차이를 이해한다.
  • eventHandler 함수를 만들고, eventHandler의 첫 번째 인자를 사용할 수 있다.

문제 1

let menus = document.querySelectorAll("button"); //모든 버튼을 가져옵니다.

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

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

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

근데 이거 하는데 뭔소린지 모르겠음 let currentMenu에 뭔갈 채우라는데 value 쓰니까 안나옴

결론

function handleClick(event) {
  console.log("working?");
  let currentMenu = event.target.textContent; // 파라미터, 타겟, 내용
  console.log(currentMenu + "를 클릭하셨습니다.");
}
  1. 파라미터를 입력해 이벤트가 일어나면 그 이벤트의 사건? 실행을 가져와야하기에 이벤트 리스너는 파라미터를 꼭 써줘야함
  2. target : 실제 이벤트가 일어나고 있는 요소를 선택, 상대적임
  3. 이번엔 입력돼있는 것이라 textContent를 썼음, input태그 같은 입력되는 것은 value로 쓰는 것이 맞음, 참고

문제 2

이벤트 구현, 핸들러리스너 비교

<div>
  <div>hello</div>
  <div id="world">world</div>
  <span id="code">code</span>
  <span>states</span>
  <button id="apply">apply</button>
</div>
// 핸들러: 하나의 이벤트만
function displayAlert() {
  alert("코드스테이츠에 오신 것을 환영합니다");
}
document.querySelector("#apply").onclick = displayAlert;
// 리스너
document.querySelector("#apply").addEventListener("click", function () {
  alert("코드스테이츠에 오신 것을 환영합니다");
});

onclick 이벤트에 함수를 할당해줬는데 호출문(실행문)이 아니라!!! 함수 자체를 할당해야줘함!

추가: 알면 좋은 이벤트

  • onsubmit
  • onchange
  • onmouseover
  • onkeyup(down)
  • event.preventDefault

+ Git Convention 보고 따라하자, 기능 단위로 쪼개 커밋, 컨벤션에 맞게 로그 남기기

profile
코뿔소처럼 저돌적으로

0개의 댓글