들어가며
자바스크립트는 웹 브라우저라는 특별한 환경에서 동작할 때 진가를 발휘합니다. 단순히 콘솔 로그로 결과를 확인하는 데서 나아가, 실제 웹 페이지의 요소들을 조작하고, 사용자 입력에 반응하며, 서버와 데이터를 주고받으며, 영구적으로 클라이언트 측 데이터를 저장하는 등 다양한 업무를 수행할 수 있습니다.
본 글에서는 브라우저 환경에 특화된 자바스크립트 기술을 다룹니다. **DOM(Document Object Model)**을 통한 웹 페이지 구조 접근 및 조작, 이벤트 핸들링으로 사용자 상호작용 처리, Fetch API 및 AJAX로 서버와 통신하기, **웹 스토리지(Local/Session Storage)**로 클라이언트 측 데이터 유지, 그리고 폼 처리와 유효성 검사를 통해 안정적인 사용자 입력 관리까지 폭넓게 다루며, 실제 웹 서비스를 구축할 수 있는 기초 역량을 쌓아봅니다.
1. DOM(Document Object Model) 기초
1-1. DOM이란 무엇인가?
DOM은 HTML 문서를 구조화된 객체 형태로 표현한 인터페이스로, 자바스크립트로 접근하고 조작할 수 있는 계층적 모델입니다. 즉, <html>, <head>, <body>와 같은 태그들이 트리 구조로 표현되고, 각 노드는 자바스크립트 객체로 변환되어 있습니다.
[html]
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>DOM 예제</title>
</head>
<body>
<h1 id="title">Hello</h1>
<p class="description">이 문장은 설명문입니다.</p>
<script>
console.log(document); // 웹 페이지 전체를 나타내는 Document 객체
</script>
</body>
</html>
document 객체는 DOM 접근의 시작점입니다. HTML 요소를 선택하고, 속성을 읽고, 텍스트를 변경하고, 새로운 요소를 추가하거나 제거하는 등의 모든 DOM 조작은 document를 통해 이루어집니다.
1-2. 요소 선택 방법
DOM 조작의 첫 단계는 원하는 요소를 선택하는 것입니다.
- document.getElementById('title') : id로 요소 찾기
- document.querySelector('CSS 셀렉터') : CSS 선택자로 첫 번째 해당 요소 반환
- document.querySelectorAll('CSS 셀렉터') : 해당 요소 전부를 NodeList로 반환
예제
[js]
const title = document.getElementById('title');
const desc = document.querySelector('.description');
1-3. 요소 내용 및 속성 조작
선택한 요소의 텍스트를 변경하거나 스타일 속성을 변경할 수 있습니다.
[js]
title.textContent = '안녕하세요!';
desc.style.color = 'blue';
또한, 클래스를 추가하거나 제거하여 스타일을 동적으로 변경할 수도 있습니다.
[js]
desc.classList.add('highlight');
1-4. 새로운 요소 생성 및 삽입
DOM 조작은 정적인 HTML 구조를 동적으로 변화시킬 수 있게 해줍니다.
[js]
const newItem = document.createElement('li');
newItem.textContent = '새로운 항목';
document.querySelector('ul').appendChild(newItem);
이렇게 하면 자바스크립트로 HTML 문서에 새로운 콘텐츠를 실시간으로 추가할 수 있습니다.
정리
DOM을 이해하고 조작하는 것은 동적인 웹 애플리케이션 개발의 핵심입니다. 이 기본기를 바탕으로 사용자 상호작용을 처리하는 이벤트 모델로 나아가봅시다.
2. 이벤트 모델과 이벤트 핸들링
2-1. 이벤트란 무엇인가?
이벤트(Event)는 사용자 액션(클릭, 키보드 입력, 마우스 이동, 스크롤)이나 시스템 변화(페이지 로드, 미디어 재생)와 같이 특정한 상황에서 발생하는 신호입니다. 자바스크립트는 이러한 이벤트에 반응하는 함수를 등록할 수 있습니다.
2-2. 이벤트 리스너 등록
addEventListener 메서드를 사용하여 특정 요소에 이벤트 핸들러를 붙일 수 있습니다.
[js]
const button = document.querySelector('button');
button.addEventListener('click', () => {
alert('버튼이 클릭되었습니다!');
});
이로써 사용자가 버튼을 클릭할 때마다 지정한 콜백 함수가 실행되어 알림창이 뜹니다.
2-3. 이벤트 객체(Event Object) 활용
이벤트 핸들러 함수는 이벤트 객체를 인자로 받아, 이벤트 타입, 타겟 요소, 커서 위치, 키보드 값 등 다양한 정보를 얻을 수 있습니다.
[js]
document.addEventListener('keydown', (event) => {
console.log(`키를 눌렀습니다: ${event.key}`);
});
2-4. 이벤트 전파(Bubbling & Capturing)
DOM 이벤트는 트리 구조 상위/하위 요소 사이를 전파됩니다. 이벤트 버블링(Bubbling)은 하위 요소에서 발생한 이벤트가 상위 요소로 전파되는 현상입니다. 때때로 이벤트 위임(Event Delegation) 기법을 활용해 효율적인 이벤트 처리를 구현할 수 있습니다.
정리
이벤트 핸들링을 통해 웹 페이지는 단순한 정보 제공에서 벗어나 사용자의 입력과 액션에 즉시 반응하는 동적인 인터페이스를 구현할 수 있습니다. 다음은 서버와 데이터를 교환하는 Fetch API 및 AJAX 기술을 살펴보겠습니다.
3. Fetch API 및 AJAX : 비동기 데이터 통신
3-1. AJAX란 무엇인가?
AJAX(Asynchronous JavaScript and XML)는 웹 페이지가 전체를 새로 고치지 않고도 서버와 데이터를 교환해, 동적인 콘텐츠 업데이트를 가능케 하는 기술 집합을 의미합니다. 최근에는 XML 대신 JSON 포맷을 주로 사용합니다.
3-2. Fetch API 소개
Fetch API는 현대적인 비동기 요청을 처리하는 표준 인터페이스로, 프로미스(Promise)를 기반으로 설계되어 사용이 간편합니다.
[js]
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
console.log(data); // 서버로부터 받은 JSON 데이터
})
.catch(error => console.error('에러 발생:', error));
3-3. async / await와 함께 쓰기
async/await 문법을 사용하면 비동기 요청 코드를 동기 코드처럼 명확히 표현할 수 있습니다.
[js]
async function loadData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
} catch(e) {
console.error(e);
}
}
loadData();
3-4. CORS, 인증, 에러 처리
실제 서비스에선 CORS(Cross-Origin Resource Sharing) 이슈나 API 키, 토큰 인증, 네트워크 오류 등 다양한 상황을 고려해야 합니다. 에러 처리를 적절히 수행하고, 실패 시 대체 동작을 구현해 안정적인 사용자 경험을 제공할 수 있습니다.
정리
서버와 데이터를 자유롭게 주고받을 수 있게 되면, 정적인 페이지를 넘어 실시간 정보 업데이트나 대화형 서비스 구현이 가능해집니다. 이제 브라우저 내 데이터 저장소인 웹 스토리지를 활용해 클라이언트 측 상태를 유지하는 방법을 알아봅시다.
4. 웹 스토리지(Local / Session Storage) 활용
4-1. Local Storage와 Session Storage 개념
- Local Storage : 데이터가 브라우저에 영구적으로 저장되어, 페이지를 새로고침하거나 브라우저를 닫았다 다시 열어도 유지됩니다.
- Session Storage : 브라우저 탭 세션 동안만 데이터가 유지됩니다. 탭을 닫으면 데이터가 사라집니다.
둘 다 key-value 형태로 문자열 데이터를 저장하며, JSON.stringify()와 JSON.parse()를 활용해 복잡한 객체도 저장 가능합니다.
4-2. Local Storage 사용 예제
[js]
localStorage.setItem('username', 'Alice');
const storedName = localStorage.getItem('username'); // 'Alice'
localStorage.removeItem('username'); // 데이터 삭제
4-3. 간단한 앱 상태 유지하기
Todo 리스트나 사용자 설정(다크모드 여부, 최근 검색어)을 로컬 스토리지에 저장하면, 사용자가 재접속할 때 이전 상태를 복원할 수 있습니다.
정리:
웹 스토리지를 이용하면 별도의 백엔드 없이도 최소한의 데이터 지속성을 제공할 수 있습니다. 다음은 폼 처리와 유효성 검사를 통해 사용자 입력을 안정적으로 관리하는 방법을 살펴봅시다.
5. Form 처리 및 유효성 검사 : 안전하고 올바른 데이터 수집
5-1. Form 기본 동작 파악하기
HTML <form> 요소는 기본적으로 submit 이벤트 발생 시 페이지를 새로 고침하며, 서버로 데이터를 전송하는 역할을 합니다. 자바스크립트를 사용하면 이 과정을 제어하고, 유효한 입력만 서버로 보내거나 AJAX로 처리할 수 있습니다.
[js]
const form = document.querySelector('form');
form.addEventListener('submit', (event) => {
event.preventDefault(); // 기본 전송 막기
// 폼 데이터 검증 및 서버 전송 로직
});
5-2. 유효성 검사(Validation)
사용자 입력이 올바른 형식인지 확인하는 것은 매우 중요합니다. 예를 들어, 이메일 필드가 비어있거나 이메일 형식이 아니면 경고 메시지를 표시하고 제출을 막을 수 있습니다.
[js]
const emailInput = document.querySelector('#email');
if (emailInput.value.trim() === '') {
showError('이메일을 입력해주세요.');
} else if (!/^[^@]+@[^@]+\.[^@]+$/.test(emailInput.value)) {
showError('올바른 이메일 주소를 입력해주세요.');
} else {
// 유효성 통과 - 서버 전송 혹은 AJAX 처리
}
5-3. 사용자 피드백 제공하기
잘못된 입력에 대해 실시간으로 빨간 테두리를 표시하거나, 폼 하단에 에러 메시지를 제공할 수 있습니다. 이런 UX 개선을 통해 사용자는 문제를 쉽게 파악하고 올바른 입력을 할 수 있습니다.
정리
폼 처리와 유효성 검사를 통해 사용자의 잘못된 입력으로 인한 오류나 보안 문제를 예방할 수 있습니다. 이는 실용적인 웹 애플리케이션 개발에서 빼놓을 수 없는 요소입니다.
마무리 : 브라우저 환경 이해로 사용자 중심 웹 애플리케이션 제작하기
여기까지 브라우저 환경에서 자바스크립트를 활용하는 핵심 기술들을 살펴보았습니다.
- DOM 조작 : 페이지 구조에 자유롭게 접근, 요소 추가/변경/삭제
- 이벤트 핸들링 : 사용자 액션에 실시간 반응, 상호작용성 극대화
- Fetch API & AJAX : 서버와 비동기 데이터 교환, 동적 콘텐츠 제공
- 웹 스토리지 : 클라이언트 측 데이터 지속성 확보, 사용자 환경 맞춤화
- Form 처리 & 유효성 검사 : 품질 높은 데이터 수집, 사용자 친화적 입력 환경
이런 기술들을 모두 익히면, 정적인 페이지를 넘어 동적인 사용자 경험, 실시간 데이터 반영, 상태 유지, 안정적인 폼 처리가 가능한 풍부한 웹 애플리케이션을 구현할 수 있습니다. 다음 단계에서는 문제 해결 및 디버깅 기법을 다루며, 개발자로서의 안정적이고 효율적인 코드 관리 역량을 향상시켜보겠습니다.
'프로그래밍 > Javascript' 카테고리의 다른 글
[Javascript] 프레임워크 & 라이브러리 기초 : 생산성과 확장성으로 가는 길 (2) | 2024.12.08 |
---|---|
[Javascript] 실전 프로젝트 : 작지만 탄탄한 예제로 자바스크립트 역량 강화하기 (1) | 2024.12.08 |
[Javascript] 문제 해결 & 디버깅 : 안정적인 코드를 위한 핵심 역량 (2) | 2024.12.07 |
[Javascript] 자바스크립트 핵심 문법 심화 : 현대적 언어 기능으로 성장하기 (0) | 2024.12.07 |
[Javascript] 자바스크립트 기초 입문 : 웹 개발자로 가는 첫걸음 (2) | 2024.12.07 |