JS 정리
자바스크립트(Javascript)를 배우는 이유?
웹 페이지 내에 있는 HTML 요소를 동적으로 변경하기 위함
- HTML 요소를 변경할 수 있는 조작 객체 : DOM(Document Object Model)
HTML 요소를 조작하기 위한 단계
- 해당 HTML 요소를 **
선택
**한다. - 선택한 HTML 요소를 **
조작
**한다.
DOM (Document Object Model)
💡 DOM : 웹 페이지 자체를 구조화된 객체로써 제공 (HTML 요소를 객체 트리로 표현)
- HTML 요소 자체를 트리 구조로 객체로 제공해줍니다 (document 객체 - 접근 API)

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
- 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>`
- .innerHTML : Element 요소 내의 모든 HTML // "
안녕하세요!
안녕히가세요
" - .innerText : 시각적으로 보여지는 모든 텍스트 // "안녕하세요!"
- .textContent : 모든 텍스트 (숨겨진 텍스트도 포함) // "안녕하세요! 안녕히가세요"
- Element 속성(Tag내의 attributes) 변경
- divTag.getAttribute("myattr") : myattr 속성의 값을 가져오기
- divTag.setAttribute("myattr", "newValue") : myattr 속성값을 "newValue"로 변경하기
- .innerHTML : Element 요소 내의 모든 HTML // "
-
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 (자동 세미클론 삽입)
자바스크립트 엔진이 자동으로 모든 코드의 끝인 ;
(세미콜론)을 자동으로 삽입해주는 것을 일컫는다.
→ 자동으로 삽입되는 세미콜론을 우리가 믿어도 되는가??
**⇒ 개발자들의 생각에 따라 다르다!**
-
ASI 일관성이 없는 동작 간혹가다 보여주는 경우가 있다..(예시코드)
javascriptfunction func1(arg) { return { key: "value" } } console.log(func1()) // {key: "value"} function func2() { return { key: "value" } } console.log(func2()) // undefined
→ 이러한 ASI를 보장하기 위해 일관적으로 코드를 작성하면 문제가 되지 않는다 (줄바꿈 주의)
💡 TypeScript(타입을 명시해서 사용하는 자바스크립트) 학습을 할 때에.
;
명시적으로 사용하는 거를 필수적으로 사용함.