인터랙티브 기능과 API
AI와 함께 동적 웹 기능을 만들어요 — API 데이터 페칭, 검색 및 필터 인터페이스, 로딩 상태 처리, 접근 가능한 컴포넌트.
프리미엄 강좌 콘텐츠
이 레슨은 프리미엄 강좌의 일부예요. Pro로 업그레이드하면 모든 프리미엄 강좌와 콘텐츠를 이용할 수 있어요.
- 모든 프리미엄 강좌 이용
- 1000개 이상의 AI 스킬 템플릿 포함
- 매주 새로운 콘텐츠 추가
🔄 복습: 지난 레슨에서 바닐라 JavaScript로 인터랙티비티를 추가했어요 — DOM 조작, 이벤트 핸들링, 폼 검증. 이제 외부 데이터 소스에 연결하고 진짜 동적 기능을 만들어볼게요.
API에서 데이터 페칭
기본 API 호출 패턴
Write vanilla JavaScript to fetch data from a REST API:
API endpoint: [URL or describe the API]
Expected response format: JSON array of objects with [describe fields]
Requirements:
- Use async/await with fetch()
- Show a loading indicator while fetching
- Handle HTTP errors (check response.ok)
- Handle network errors (try-catch around the fetch)
- Display data in the page using safe DOM methods (createElement + textContent)
- Show a user-friendly error message if the fetch fails
- Add a timeout (abort after 10 seconds using AbortController)
Vanilla JavaScript, no dependencies.
로딩, 에러, 빈 상태
데이터 기반 기능은 해피 패스 외에 세 가지 상태가 필요해요:
Write vanilla JavaScript to manage UI states for an API-powered feature:
States to handle:
1. Loading: Show a spinner/skeleton while data loads
2. Success: Display the data
3. Error: Show a friendly message with a retry button
4. Empty: Show a "no results" message when the API returns an empty array
Requirements:
- Single function that manages state transitions
- Retry button re-fetches the data
- Loading spinner is accessible (aria-live="polite" announcement)
- Error messages don't expose technical details to users
Provide the HTML structure, CSS for each state, and JavaScript.
✅ 확인 질문: “빈” 상태를 “성공"과 분리해서 처리하는 이유는?
빈 결과는 데이터가 있는 성공과 달라요. 사용자가 “xyzabc"를 검색해서 결과가 없는데 빈 페이지를 보여주면 고장난 것처럼 느껴져요. “‘xyzabc’에 대한 결과가 없어요 — 다른 검색어를 시도해보세요"라고 보여주면 검색은 작동했지만 일치하는 것이 없다는 걸 알려줘요. 빈 상태는 소통의 기회예요.
검색과 필터 인터페이스
클라이언트 사이드 검색
Write a real-time search filter in vanilla JavaScript:
Data: An array of objects displayed as cards on the page
Search behavior:
- Filter as the user types (debounced, 300ms delay)
- Search across multiple fields: [title, description, category]
- Case-insensitive matching
- Show result count ("Showing X of Y items")
- Show "No results" message when nothing matches
- Clear button to reset the search
Requirements:
- Debounce the input handler (don't filter on every keystroke)
- Highlight matching text in results (wrap matches in a mark element)
- Maintain URL state (add search query as URL parameter so it survives refresh)
- Accessible: announce result count changes to screen readers
Vanilla JavaScript, no dependencies.
네이버나 다음 같은 한국 검색 엔진에서도 실시간 검색어 자동 완성을 볼 수 있어요. 같은 원리를 여러분의 웹사이트에 적용하는 거예요 — 사용자가 타이핑하면 즉시 결과가 필터링되는 경험이에요.
멀티 필터 인터페이스
Write a filter system for a listing page:
Filter types:
- Category (checkboxes, multiple selection)
- Difficulty (radio buttons, single selection)
- Sort (dropdown: newest, oldest, alphabetical)
Requirements:
- Filters combine with AND logic (category AND difficulty)
- URL updates with filter state (shareable filter URLs)
- Active filter count displayed ("3 filters active")
- "Clear all filters" button
- Smooth transition when items show/hide
- Filter counts update to show available items per option
Vanilla JavaScript, no dependencies.
일반적인 인터랙티브 컴포넌트 만들기
탭
Write an accessible tabs component in vanilla JavaScript:
Requirements:
- Tab list with role="tablist"
- Tab buttons with role="tab", aria-selected, aria-controls
- Tab panels with role="tabpanel", aria-labelledby
- Keyboard navigation: Arrow keys move between tabs, Enter/Space selects
- Only the selected tab panel is visible
- Support for dynamic tab content (loaded on tab switch)
Follow WAI-ARIA Tabs pattern. Vanilla JavaScript, no dependencies.
모달/다이얼로그
Write an accessible modal dialog in vanilla JavaScript:
Requirements:
- Opens on trigger button click
- Traps focus inside the modal (Tab cycles through modal elements only)
- Closes on Escape key, overlay click, and close button
- Returns focus to trigger button when closed
- Uses role="dialog" and aria-modal="true"
- Prevents background scroll when open
- Smooth open/close animation with CSS
Follow WAI-ARIA Dialog pattern. Vanilla JavaScript, no dependencies.
✅ 확인 질문: 모달에서 포커스 트래핑이 중요한 이유는?
포커스 트래핑 없이 키보드 사용자가 모달에서 Tab을 누르면, 모달 뒤에 보이지 않는 배경 페이지를 탭으로 이동하게 돼요. 볼 수 없는 버튼과 링크와 상호작용할 수 있어요. 이것은 혼란스럽고, 의도하지 않은 폼을 제출하는 등 위험할 수 있어요. 포커스 트래핑은 키보드 사용자가 의도적으로 닫을 때까지 모달 안에 머물게 해요.
연습: 동적 기능 만들기
- 최소 12개 항목의 검색과 필터 인터페이스를 만드세요
- 무료 공개 API(예: JSONPlaceholder)에서 데이터를 페칭하고 로딩과 에러 상태를 처리하세요
- 콘텐츠 정리를 위한 접근 가능한 탭 컴포넌트를 만드세요
- 모든 기능이 키보드만으로 작동하는지 테스트하세요
- 일부러 잘못된 API URL을 사용해서 에러 상태를 테스트하세요
핵심 정리
- async/await는 API 호출을 읽기 쉽고 디버깅하기 쉽게 만들어요 — 중첩된 .then() 체인보다 선호하세요
- 모든 API 호출에 세 가지 상태가 필요해요: 로딩(스피너), 에러(친절한 메시지 + 재시도), 빈 상태(도움이 되는 안내)
- API 키를 클라이언트 사이드 코드에 절대 노출하지 마세요 — 인증이 필요한 API 호출에는 서버 사이드 프록시를 사용하세요
- 검색 인풋에 디바운스(300ms 지연)를 적용해서 매 키 입력마다 필터링하는 것을 방지하세요
- 인터랙티브 컴포넌트(탭, 모달, 아코디언)는 키보드와 스크린 리더 접근성을 위해 WAI-ARIA 패턴을 따라야 해요
- 필터/검색 상태로 URL을 업데이트해서 사용자가 특정 뷰를 공유하고 북마크할 수 있게 하세요
다음 레슨: 디버깅과 성능 최적화를 마스터해요 — 버그를 더 빠르게 찾고 사이트를 즉시 로드되게 만드는 법.
이해도 체크
먼저 위의 퀴즈를 완료하세요
레슨 완료!