background
Next.js10분

JS 정리

2024년 11월 22일

자바스크립트(Javascript)를 배우는 이유?

웹 페이지 내에 있는 HTML 요소를 동적으로 변경하기 위함

  • HTML 요소를 변경할 수 있는 조작 객체 : DOM(Document Object Model)

HTML 요소를 조작하기 위한 단계

  1. 해당 HTML 요소를 **선택**한다.
  2. 선택한 HTML 요소를 **조작**한다.

DOM (Document Object Model)

💡 DOM : 웹 페이지 자체를 구조화된 객체로써 제공 (HTML 요소를 객체 트리로 표현)

  • HTML 요소 자체를 트리 구조로 객체로 제공해줍니다 (document 객체 - 접근 API)

image.png

image.png

image.png

image.png

  • DOM 요소의 상위 객체
    • document : DOM 트리의 최상위 객체
    • document**.documentElement** : HTML 요소를 표현하는 객체
    • document**.body** : body 요소를 표현하는 객체
    • document**.head** : head 요소를 표현하는 객체
    • document**.title** : title 요소를 표현하는 객체
    • document**.location** : 현재 브라우저 내의 주소를 표현하는 객체
      • document.location.href : 현재 브라우저의 URL 주소를 문자열로 가지고 있는 속성
  • DOM Tree 구조, 부모↔자식 관계 접근
    • 자식으로 넘어갈 때...
      • bodyTag**.childNodes** : body 요소의 자식 요소를 선택 (Node 타입)
      • bodyTag**.children** : body 요소의 자식 요소를 선택 (Element 타입)
    • 부모로 넘어갈 때...
      • child_1**.parentNode** : child_1 요소의 부모 요소를 선택 (Node 타입)
      • child_1**.parentElement** : child_1 요소의 부모 요소를 선택 (Element 타입)

HTML 요소의 타입

image.jfif

image.jfif

  • Node : 모든 HTML 요소는 Node 타입을 상속 받아 구현되어 있음
    • text : HTML tag 내에 있는 content 문자열 내용들의 타입
    • element : HTML tag 를 나타내는 DOM 객체 타입
    • comment : <!-- 이것은 참고용 주석입니다 --> 주석에 대한 타입
    • CDATA : 해당 자료가 어떠한 타입인지를 나타내는 메타정보

HTML 요소 선택

  • document.querySelect(”CSS선택자”) : 단일 Node 하나를 선택하는 메서드
    • 반환 타입이 Node 타입으로 반환 (*선택된 요소가 없는 경우 null)
  • document.querySelectAll(”CSS 선택자”): 여러개의 Node를 선택하는 메서드
    • 반환 타입이 NodeList 타입으로 반환 (*비어있는 NodeList 로 반환)
html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <h1 id="myHeading" class="heading">DOM 선택</h1>
    <a href="https://www.google.com/">google</a>
    <p class="content" name="myContent">content1</p>
    <p class="content">content2</p>
    <p class="content">content3</p>
    <ul>
      <li>list1</li>
      <li>list2</li>
    </ul>
    <!-- 
     DOM 조작 방법 (JS 사용)
     1. HTML 요소를 선택(찾기)
     - document.querySelector('CSS선택자') : css선택자를 가진 모든 HTML 요소 중에 첫번째 요소를 찾는 메서드 (Node)
     - document.querySelectorAll('CSS선택자') : CSS선택자를 가진 모든 HTML 요소를 찾는 메서드 (NodeList)
     - document.getElementById('ID속성') : ID 속성을 가진 element 요소를 찾는 메서드
     - document.getElementByClassname("class속성") : class 속성을 가진 element 요소를 찾는 메서드
	   
     2. HTML 요소를 조작(변경)
     - Text 속성 변경
     - Element 속성 변경 (tag 내 속성)
     - Style 속성 변경
     -->
    <script>
      // 1. querySelector 를 사용해서 h1 태그를 선택해보기
      const h1Tag = document.querySelector("h1");
      console.log(h1Tag);
      // 2. querySelectorAll              //
      const h1Tags = document.querySelectorAll("h1");
      console.log(h1Tags);
      // 3. querySelector 를 사용해서 ul 태그 하위에 있는 li 태그 선택해보기
      const liTag = document.querySelector("ul > li");
      console.log(liTag);
      // 4. querySelectorAll             //
      const liTags = document.querySelectorAll("ul > li");
      console.log(liTags);
      // 해당되는 요소가 없다면???
      const tag1 = document.querySelector("h3"); // null 반환
      console.log(tag1);
      const tag2 = document.querySelectorAll("h3"); // 비어있는 NodeList 로 반환
      console.log(tag2);

      // etc. 다른 HTML 요소 선택자 메서드들... Element 타입으로 반환
      // const tag3 = document.getElementById("myHeading");
      const tag3 = document.querySelector("#myHeading");
      console.log(tag3);

      // const tag4 = document.getElementsByClassName("heading");
      const tag4 = document.querySelector(".heading");
      console.log(tag4);

      // const tag5 = document.getElementsByTagName("h1");
      const tag5 = document.querySelector("h1");
      console.log(tag5);

      // const tag6 = document.getElementsByName("myContent");
      const tag6 = document.querySelector("[name='myContent']");
      console.log(tag6);
    </script>
  </body>
</html>

HTML 요소를 조작

  • 텍스트 속성 변경 <li>안녕하세요!</li> -> <li>안녕히가세요</li> ex) liTag.textContent = "안녕히가세요";

    `<li><p>안녕하세요!</p><p style="block:none;">안녕히가세요</p></li>`
    
    1. .innerHTML : Element 요소 내의 모든 HTML // "

      안녕하세요!

      안녕히가세요

      "
    2. .innerText : 시각적으로 보여지는 모든 텍스트 // "안녕하세요!"
    3. .textContent : 모든 텍스트 (숨겨진 텍스트도 포함) // "안녕하세요! 안녕히가세요"
    • Element 속성(Tag내의 attributes) 변경
    • divTag.getAttribute("myattr") : myattr 속성의 값을 가져오기
    • divTag.setAttribute("myattr", "newValue") : myattr 속성값을 "newValue"로 변경하기
  • Element의 Class 속성 변경 (classList):

    • .classList.add('클래스명') : 클래스 추가
    • .classList.remove('클래스명') : 클래스 제거
    • .classList.toggle('클래스명') : 클래스가 있음->제거 / 없음->추가
    • .classList.contains('클래스명') : 클래스가 존재하는지 유무 체크
  • Element의 Style 속성 변경 *CSS 속성의 정의할 때에 해당 속성명의 kekbab-case의 글자 -> camelCase로 변경!

    • const styleString = tag1.style;

    • const value = tag1.style.스타일속성명;

    • tag1.style.스타일속성명 = "변경하고자하는값"; ex1) tag1 의 글자 색상을 변경하겠다. (color) tag1.style.color = "red";

      ex2) tag1 의 뒷 배경 색상을 파란색으로 변경하겠다. (background-color -> backgroundColor) tag1.style.backgroundColor = "blue";

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <h1 id="myHeading" class="heading aaa bbb ccc">DOM 선택</h1>
    <a href="https://www.google.com/">google</a>
    <p class="content" name="myContent" style="color: red">content1</p>
    <p class="content" my-custom-attribute="myValue">content2</p>
    <p class="content">content3</p>
    <ul>
      <li>list1</li>
      <li>list2</li>
    </ul>
    <!-- 
      <li><p>안녕하세요!</p><p style="block:none;">안녕히가세요</p></li>
      1. .innerHTML   : Element 요소 내의 모든 HTML // "<p>안녕하세요!</p><p>안녕히가세요</p>"
      2. .innerText   : 시각적으로 보여지는 모든 텍스트 // "안녕하세요!"
      3. .textContent : 모든 텍스트 (숨겨진 텍스트도 포함)  // "안녕하세요! 안녕히가세요"

     - Element 속성(Tag내의 attributes) 변경
       - divTag.getAttribute("myattr") : myattr 속성의 값을 가져오기
       - divTag.setAttribute("myattr", "newValue") : myattr 속성값을 "newValue"로 변경하기
       
       - Element의 Class 속성 변경 (classList):
         .classList.add('클래스명') : 클래스 추가
         .classList.remove('클래스명') : 클래스 제거
         .classList.toggle('클래스명') : 클래스가 있음->제거 / 없음->추가
         .classList.contains('클래스명') : 클래스가 존재하는지 유무 체크 
       
        - Element의 Style 속성 변경
          *CSS 속성의 정의할 때에 해당 속성명의 kekbab-case의 글자 -> camelCase로 변경!
          - const styleString = tag1.style;
          - const value = tag1.style.스타일속성명;
          - tag1.style.스타일속성명 = "변경하고자하는값";
          ex1) tag1 의 글자 색상을 변경하겠다. (color)
          tag1.style.color = "red";
          
          ex2) tag1 의 뒷 배경 색상을 파란색으로 변경하겠다. (background-color -> backgroundColor)
          tag1.style.backgroundColor = "blue";
     -->
    <script>
      // *조작하기 전에 요소 선택은 필수!
      // 텍스트 조작
      console.log(pTag.innerHTML);
      // pTag.innerHTML = "안녕하세요";
      // pTag.innerText = "안녕하세요";
      // pTag.textContent = "안녕하세요";
      // pTag.innerHTML = `<div>Hi!</div><div>Hi!</div><div>Hi!</div><div>Hi!</div><div>Hi!</div>`;
      pTag.textContent = `<div>Hi!</div><div>Hi!</div><div>Hi!</div><div>Hi!</div><div>Hi!</div>`;

      // h1 태그의 클래스 속성 가져오기
      // 1. h1 태그를 선택
      const h1Tag = document.querySelector("h1");
      // 2. h1 태그를 조작 (class 속성 가져오기)
      const classValue = h1Tag.getAttribute("class"); // 'class'의 속성값 가져오기
      console.log(classValue);
      // h1태그에 my-new-attribute 속성에 "myValue"라는 값을 넣기!
      h1Tag.setAttribute("my-new-attribute", "myValue");

      // class 속성에 'ddd' 속성값 추가하기
      // h1Tag.setAttribute("class", "ddd"); // 이렇게 하면 class 속성값이 'ddd'로 할당되어버린다.
      // h1Tag.setAttribute("class", classValue + " ddd");

      // 만약에 class 속성에다가 특정 값을 빼거나, 넣거나 하고 싶은 경우는??
      // -----> 어떻게 해줘야할까?? 윗처럼 문자열로 접근하게 되면 문자열을 찾아서 치환! (복잡)
      h1Tag.classList.add("ddd"); // 'ddd'라는 클래스가 class 속성에 추가
      h1Tag.classList.remove("ddd"); //   //                        삭제
      console.log(h1Tag.classList.contains("dark-mode")); // 'dark-mode' 클래스 유무 체크
      h1Tag.classList.toggle("dark-mode"); // 'dark-mode' 클래스 토글
      console.log(h1Tag);
      console.log(h1Tag.classList.contains("dark-mode")); // 'dark-mode' 클래스 유무 체크
    </script>
  </body>
</html>

DOM 조작 (Element 생성)

→ 특정 HTML 요소에 자식 요소로서 **새로운 HTML 요소를 생성(추가)**하는 방법

💡 예전 방법으로는... 문자열로서 추가하는 방법이 있었으나, XSS 공격 등의 보안 이슈로 인하여 문자열로 HTML 요소를 삽입하는 방법은 사장되었다. (지양한다)
divTag.innerHTML = "<p>새로운 자식1</p><p>새로운 자식2</p><p>새로운 자식3</p>";

DOM에서 지원하는 HTML 요소 생성 메서드를 활용 (권장)

💡 단, DOM에 객체(element 노드 같은)를 추가하거나 삭제하는 경우,
원본 객체가 단 한개만 존재하도록 처리되어 있다…!

  • document.createElement(”p”) : 새로운 Element 객체를 생성 <p></p>
  • divTag.appendChild(newElement) : 요소 newElement를 divTag의 자식으로 추가
  • divTag.removeChild(newElement) : 요소 newElement를 div Tag의 자식에서 제거
  • newElement.remove() : 해당 newElement 삭제

자바스크립트 내에 변수 선언

javascript
함수스코프 : 호이스팅O
블록스코프 : {} 스코프 내에서 생성/소멸 된다 (호이스팅x)
  • var : (레거시, 옛날부터 사용한 변수 선언 키워드)
    • 재선언 O, 재할당 O,
  • const(상수) : 재할당 불가, 블록스코프(호이스팅x)
  • let (변수): 재할당 가능 ,블록스코프(호이스팅x)
javascript
// 1. var 예시
// 호이스팅 현상도 발생!
console.log(name);

// 여러번 재선언, 재할당 가능!
var name = "gildong";
console.log(name);
name = "hong"; // 재할당
console.log(name);
var name = "minsu"; // 재선언
console.log(name);

// 외부 스코프, 내부 스코프, 함수 내에서도 (마치 전역 변수처럼)
if (true) {
  console.log(name);
  var x = 10;
  const y = 3;
  let z = 4;
  // let z = 10; // 재선언 불가!
  z = 14; // 재할당 O
  console.log(x, y, z);
}
console.log(x);
console.log(y); // ERROR! 소멸되었으므로 출력불가!
console.log(z); // ERROR! 소멸되었으므로 출력불가!

호이스팅(hositing)

호이스팅이란,,, 이후에 할당된 변수나, 함수들을 마치 위에 “끌어올려진(선언된) 것처럼” 동작하는 것을 의미한다.

javascript
// 최상단에 해당 변수나 함수가 선언된 것처럼 동작!
// var x = undefined;
// function func1(){...};
// var func2 = undefined;

console.log(x); // undefined ? 1. 에러 / 2.잘 실행된다. / 3.무언가 출력된다(undefined) / 4. 쓰레기값이 나온다
var x = 5;
console.log(x); // 5

func1();
console.log("aaaa");
// 함수도 동일한 방식으로 동작한다 (호이스팅 현상이 일어남)
function func1() {
  console.log("hello");
}
func1();

//   func2(); // 에러!
console.log("bbbbb");
// 함수를 변수에 감싸서 호이스팅 현상이 일어나게 한다면??
var func2 = function () {
  console.log("ㅎㅎㅎㅎㅎ");
};
func2(); // 정상적으로 동작

ASI (자동 세미클론 삽입)

자바스크립트 엔진이 자동으로 모든 코드의 끝인 ; (세미콜론)을 자동으로 삽입해주는 것을 일컫는다.

→ 자동으로 삽입되는 세미콜론을 우리가 믿어도 되는가??

**⇒ 개발자들의 생각에 따라 다르다!**
  1. ASI 일관성이 없는 동작 간혹가다 보여주는 경우가 있다..(예시코드)

    javascript
    function func1(arg) {
        return {
          key: "value"
        }
      }
      console.log(func1()) // {key: "value"}
      function func2() {
        return 
        {
          key: "value"
        }
      }
      console.log(func2()) // undefined
    

→ 이러한 ASI를 보장하기 위해 일관적으로 코드를 작성하면 문제가 되지 않는다 (줄바꿈 주의)

💡 TypeScript(타입을 명시해서 사용하는 자바스크립트) 학습을 할 때에. ; 명시적으로 사용하는 거를 필수적으로 사용함.

태그

#JS