JavaScript
클라이언트(브라우저, 모바일 등)만 실행되는 '프로그래밍 언어'
- 사용자의 활동과 입력 값에 따라 '동적'으로 동작하는 기능을 담당
기본 구조
연결
HTML에서 JavaScript은 사용을 위해선 HTML과의 연결이 필요하다.
- 별도의 .js 파일을 만들어 <script> 태그로 HTML <head> 안에서 연결 (가장 권장되는 방식)
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>장바구니 목록</title>
<!-- CSS 연결 -->
<link rel="stylesheet" href="./css/style.css">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700&display=swap" rel="stylesheet">
<!-- Javascript 추가 -->
<script src="./js/app.js" defer></script>
</head>
변수
// 'API_URL'이라는 변수에 Mock Server 주소(문자열)를 저장
const API_URL = 'https://[...].mock.pstmn.io/items';
// 'itemForm'이라는 변수에 HTML에서 id="item-form"인 요소를 찾아서 저장
const itemForm = document.getElementById('item-form');
// 'itemNameInput' 변수에 id="item-name"인 input 요소를 저장
const itemNameInput = document.getElementById('item-name');
- const : 한 번 저장하면 값을 바꿀 수 없는 변수
- let : 나중에 값을 바꿀 수 있는 변수
함수
// "item(데이터)을 받아서 화면(DOM)에 추가한다"는 기능을 하는 함수
function addItemToDOM(item) {
// 플레이스홀더 제거 (명령1)
const placeholderItem = document.querySelector('.placeholder-item');
if (placeholderItem) {
placeholderItem.remove();
}
// li 요소 생성 (명령2)
const li = document.createElement('li');
// ... (li에 내용물 채우기) ...
// 목록에 li 추가 (명령3)
itemList.appendChild(li);
}
- function 이름(매개변수) { ... } 형태로 생성
이벤트 리스너
사용자의 행동(이벤트)을 감지하고, 특정 이벤트가 발생했을 때 지정된 함수를 실행하도록 연결해줌
// 1. 폼 제출(submit) 이벤트 감지
// "만약 'itemForm'에서 'submit'(제출) 이벤트가 발생하면,
// 이 함수( async (e) => { ... } )를 실행시켜라!"
itemForm.addEventListener('submit', async (e) => {
e.preventDefault(); // (명령) 폼의 기본 동작(새로고침)을 막아라
// ... (새 아이템을 추가하는 나머지 로직) ...
});
// 2. 클릭(click) 이벤트 감지
// "만약 'itemList' 영역에서 'click' 이벤트가 발생하면,
// 이 함수( async (e) => { ... } )를 실행시켜라!"
itemList.addEventListener('click', async (e) => {
// (조건) 만약 클릭한 대상이 .delete-btn 클래스를 가졌다면,
if (e.target.classList.contains('delete-btn')) {
// ... (삭제를 처리하는 로직) ...
}
});
주요 기능
이벤트 처리 (Event Handling)
// 'item-form'이라는 id를 가진 <form> 태그를 선택
const itemForm = document.getElementById('item-form');
// itemForm에서 'submit' 이벤트가 발생하는지 감시
itemForm.addEventListener('submit', async (e) => {
// ... (버튼이 눌리면 이 안의 코드가 실행됨) ...
});
// 'item-list'라는 id를 가진 <ul> 태그를 선택
const itemList = document.getElementById('item-list');
// itemList 또는 그 자식들에서 'click' 이벤트가 발생하는지 감시
itemList.addEventListener('click', async (e) => {
// 만약 클릭된 요소가 'delete-btn' 클래스를 가졌다면
if (e.target.classList.contains('delete-btn')) {
// ... (삭제 버튼이 눌리면 이 안의 코드가 실행됨) ...
}
});
문서 제어(DOM Control)
이벤트가 발생하면 HTML의 값을 '읽어오거나' HTML을 '새로 써서' 화면을 변경할 수 있음
- Read
const itemNameInput = document.getElementById('item-name');
// (submit 이벤트 핸들러 내부)
const newItem = {
name: itemNameInput.value, // <input id="item-name">의 값을 읽음
price: parseInt(itemPriceInput.value), // <input id="item-price">의 값을 읽음
category: itemCategoryInput.value, // <select>의 값을 읽음
description: itemDescriptionInput.value, // <textarea>의 값을 읽음
// ... (이하 생략) ...
};
- Write
// (addItemToDOM 함수)
function addItemToDOM(item) {
// 1. (Create) <li> 태그를 메모리에 새로 생성
const li = document.createElement('li');
// 2. (Write/Modify) 생성한 <li>에 HTML 내용을 삽입
li.innerHTML = `
<img src="${item.image}" ...>
<h3>${item.name}</h3>
<p>${item.price.toLocaleString()}원</p>
`;
// 3. (Write/Append) 완성된 <li>를 <ul id="item-list">에 부착
itemList.appendChild(li);
}
// (delete 이벤트 핸들러 내부)
if (isDeleteSuccessful) {
// 4. (Delete) 클릭된 버튼의 부모 <li>를 화면에서 제거
liToRemove.remove();
}
서버와 통신 (HTTP Communication)
- JavaScript의 역할 : 객체를 JSON이라는 형태에 담아, HTTP라는 '규칙'을 통해 백엔드 서버로 '요청(Request)' 보냄
itemForm.addEventListener('submit', async (e) => {
...
if (isApiConnected) {
// --- 1. API 연결 모드 ---
try {
const response = await fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(newItem)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const addedItem = await response.json();
addItemToDOM(addedItem);
} catch (error) {
console.error("상품 추가 중 오류 발생:", error);
alert("상품을 추가하지 못했습니다. Mock Server URL 또는 응답 형식을 확인해주세요.");
}
} else {
// --- 2. Demo (Offline) 모드 ---
console.log("Demo Mode: Adding item to local view only.");
// Demo 모드에서는 삭제 기능을 위해 임시 ID를 생성 (현재 시간을 ID로 사용)
const tempItem = { ...newItem, id: String(Date.now()) };
addItemToDOM(tempItem);
}
...
});'웹 > 관련 지식' 카테고리의 다른 글
| HTTP (HyperText Transfer Protocol) (0) | 2026.05.27 |
|---|---|
| CSS (Cascading Style Sheets) (0) | 2026.05.26 |
| HTML (HyperText Markup Language) (0) | 2026.05.26 |