콘텐츠로 이동

JavaScript — 웹 페이지를 살아있게 만들기

왜 JavaScript인가?

HTML과 CSS로 만든 페이지는 정적입니다. 버튼을 눌러도 아무것도 바뀌지 않습니다.

JavaScript(JS)는 브라우저에서 실행되는 프로그래밍 언어입니다.
사용자의 행동에 반응하고, 페이지의 내용을 동적으로 바꿀 수 있습니다.

HTML  →  구조 (무엇이 있는가)
CSS   →  스타일 (어떻게 보이는가)
JS    →  동작 (어떻게 반응하는가)

기본 문법 — Python과 비교

Python을 배웠다면 JavaScript도 낯설지 않습니다.

# Python
name = "지민"
age = 20
is_done = True

if age >= 18:
    print(f"안녕하세요, {name}님")

for i in range(3):
    print(i)
// JavaScript
let name = "지민";
let age = 20;
let isDone = true;

if (age >= 18) {
  console.log(`안녕하세요, ${name}님`);
}

for (let i = 0; i < 3; i++) {
  console.log(i);
}

주요 차이점

Python JavaScript
들여쓰기로 블록 구분 { } 로 블록 구분
줄 끝에 : 줄 끝에 ; (생략 가능)
True / False true / false
print() console.log()
f"Hello {name}" `Hello ${name}`
def function

변수 선언

let x = 10;      // 재할당 가능
const y = 20;    // 재할당 불가 (상수)

x = 15;          // 가능
// y = 25;       // 오류!

var는 구형 문법입니다. 현대 JavaScript에서는 letconst만 사용하세요.

함수

// 일반 함수
function greet(name) {
  return `안녕하세요, ${name}님`;
}

// 화살표 함수 (Arrow Function) — 더 간결
const greet = (name) => {
  return `안녕하세요, ${name}님`;
};

// 한 줄이면 return 생략 가능
const add = (a, b) => a + b;

배열과 객체

// 배열 (Python의 list)
const todos = ["운동하기", "책 읽기", "공부하기"];
todos.push("산책하기");     // 추가
todos[0];                   // "운동하기"
todos.length;               // 4

// 배열 순회
todos.forEach((todo) => {
  console.log(todo);
});

// map — 변환
const upper = todos.map((t) => t.toUpperCase());

// filter — 필터링
const done = todos.filter((t) => t.length > 3);

// 객체 (Python의 dict)
const user = {
  id: 1,
  name: "지민",
  email: "[email protected]",
};

user.name;           // "지민"
user["email"];       // "[email protected]"
user.age = 20;       // 속성 추가

DOM — 페이지를 코드로 조작하기

DOM(Document Object Model)은 HTML 요소를 JavaScript로 다룰 수 있게 해주는 인터페이스입니다.

HTML 파일           브라우저 메모리 (DOM)
<h1>제목</h1>   →   document
<p>내용</p>         ├── html
                    │   ├── head
                    │   └── body
                    │       ├── h1  ("제목")
                    │       └── p   ("내용")

요소 선택

// id로 선택 (하나)
const title = document.getElementById("title");

// CSS 선택자로 선택 (첫 번째)
const btn = document.querySelector("#add-btn");

// CSS 선택자로 선택 (전부)
const items = document.querySelectorAll(".todo-item");

요소 내용 변경

const title = document.getElementById("title");

title.textContent = "새 제목";          // 텍스트 변경
title.innerHTML = "<strong>굵게</strong>"; // HTML 포함 변경
title.style.color = "red";              // 스타일 변경
title.classList.add("done");            // 클래스 추가
title.classList.remove("done");         // 클래스 제거
title.classList.toggle("done");         // 있으면 제거, 없으면 추가

새 요소 생성

// <div class="todo-item"><span>운동하기</span></div> 만들기
const item = document.createElement("div");
item.className = "todo-item";

const span = document.createElement("span");
span.textContent = "운동하기";

item.appendChild(span);
document.getElementById("todo-list").appendChild(item);

이벤트 — 사용자 행동에 반응하기

const btn = document.getElementById("add-btn");

// 클릭 이벤트
btn.addEventListener("click", () => {
  console.log("버튼이 클릭됨!");
});

// 입력 이벤트
const input = document.getElementById("title-input");
input.addEventListener("input", (event) => {
  console.log("입력값:", event.target.value);
});

// 키보드 이벤트
input.addEventListener("keydown", (event) => {
  if (event.key === "Enter") {
    console.log("Enter 키가 눌림");
  }
});

// 폼 제출 이벤트
const form = document.getElementById("todo-form");
form.addEventListener("submit", (event) => {
  event.preventDefault();  // 폼의 기본 동작(페이지 새로고침) 막기
  console.log("폼이 제출됨");
});

Todo 앱 — JavaScript로 동작 추가

10장에서 만든 HTML에 JavaScript를 연결합니다.

<!-- index.html 맨 아래 (</body> 직전) -->
<script src="app.js"></script>
// app.js
const form = document.getElementById("todo-form");
const input = document.getElementById("title-input");
const list = document.getElementById("todo-list");

// 할 일 목록 (메모리에 저장)
let todos = [];
let nextId = 1;

// 화면에 todo 목록 다시 그리기
function renderTodos() {
  list.innerHTML = "";  // 기존 목록 지우기

  todos.forEach((todo) => {
    const item = document.createElement("div");
    item.className = "todo-item" + (todo.isDone ? " done" : "");

    const checkbox = document.createElement("input");
    checkbox.type = "checkbox";
    checkbox.checked = todo.isDone;
    checkbox.addEventListener("change", () => toggleTodo(todo.id));

    const span = document.createElement("span");
    span.textContent = todo.title;

    const delBtn = document.createElement("button");
    delBtn.className = "delete-btn";
    delBtn.textContent = "삭제";
    delBtn.addEventListener("click", () => deleteTodo(todo.id));

    item.appendChild(checkbox);
    item.appendChild(span);
    item.appendChild(delBtn);
    list.appendChild(item);
  });
}

// 할 일 추가
form.addEventListener("submit", (e) => {
  e.preventDefault();
  const title = input.value.trim();
  if (!title) return;

  todos.push({ id: nextId++, title, isDone: false });
  input.value = "";
  renderTodos();
});

// 완료 토글
function toggleTodo(id) {
  todos = todos.map((t) =>
    t.id === id ? { ...t, isDone: !t.isDone } : t
  );
  renderTodos();
}

// 삭제
function deleteTodo(id) {
  todos = todos.filter((t) => t.id !== id);
  renderTodos();
}

// 초기 렌더링
renderTodos();

브라우저 개발자 도구 — Console

console.log("일반 출력");
console.warn("경고 (노란색)");
console.error("오류 (빨간색)");
console.log({ id: 1, title: "운동" });  // 객체도 출력 가능

F12 → Console 탭에서 직접 JS 코드를 실행해 볼 수 있습니다.

외부 JS 파일로 분리

project/
├── index.html
├── style.css
└── app.js
<!-- index.html 맨 아래 -->
<script src="app.js"></script>

<script> 태그는 </body> 바로 앞에 놓아야
HTML이 먼저 로드된 뒤 JavaScript가 실행됩니다.

실습 미션

미션 1: Console 탐험

브라우저 F12 → Console에서:
1. console.log("Hello") 를 실행하세요.
2. let x = [1, 2, 3]; x.map(n => n * 2) 를 실행하세요.
3. document.title 을 입력해 현재 페이지 제목을 확인하세요.

미션 2: 버튼 클릭 카운터

1. <h2 id="count">0</h2> 와 <button id="btn">+1</button> 을 만드세요.
2. 버튼을 클릭할 때마다 숫자가 1씩 증가하게 하세요.
3. 숫자가 10이 되면 배경색이 바뀌게 하세요.

미션 3: Todo 앱 완성

위 app.js 코드를 적용하고:
1. 할 일을 추가해 보세요.
2. 체크박스로 완료 처리해 보세요.
3. 삭제 버튼으로 삭제해 보세요.

미션 4 (심화): localStorage

페이지를 새로고침하면 todos 배열이 초기화됩니다.
localStorage를 사용해 데이터를 브라우저에 저장하고
새로고침 후에도 유지되게 만드세요.

힌트:
localStorage.setItem("todos", JSON.stringify(todos));
const saved = JSON.parse(localStorage.getItem("todos") || "[]");

핵심 요약

개념 설명
let / const 변수 선언 — 재할당 가능/불가
화살표 함수 (x) => x * 2 — 간결한 함수 표현
DOM HTML을 코드로 다루는 인터페이스
querySelector CSS 선택자로 요소 찾기
addEventListener 클릭, 입력 등 이벤트 처리
innerHTML / textContent 요소 내용 읽기/쓰기
preventDefault() 폼 새로고침 같은 기본 동작 막기

JavaScript는 브라우저에서 실행됩니다.
다음 장에서는 이 JavaScript로 백엔드 API를 호출하는 법을 배웁니다.