웹 개발을 하다 보면 사용자와의 상호작용을 더욱 풍부하게 만들어 주는 다양한 API들을 접하게 됩니다.
파일을 드래그 앤 드롭으로 업로드하거나, 대용량 데이터를 처리하거나, 무거운 작업을 백그라운드에서 실행하는 것들이 모두 이런 API들 덕분에 가능합니다.
이번 포스트에서는 모던 웹 개발에서 자주 사용되는 세 가지 핵심 API를 살펴보겠습니다.
📌 목차
- 드래그 앤 드롭 API
- Blob
- Web Workers
📝 드래그 앤 드롭 API
드래그 앤 드롭 API는 사용자가 마우스로 요소를 끌어서 다른 위치에 놓을 수 있게 해주는 기능입니다.
파일 업로드나 요소 재정렬에 주로 사용됩니다.
기본 구현
// HTML: <div id="dropArea">여기에 파일을 드롭하세요</div>
const dropArea = document.getElementById('dropArea');
// 드래그 오버 시 기본 동작 방지
dropArea.addEventListener('dragover', (e) => {
e.preventDefault();
dropArea.style.backgroundColor = '#f0f0f0';
});
// 드래그 떠날 때
dropArea.addEventListener('dragleave', () => {
dropArea.style.backgroundColor = '';
});
// 파일 드롭 시
dropArea.addEventListener('drop', (e) => {
e.preventDefault();
dropArea.style.backgroundColor = '';
const files = e.dataTransfer.files;
console.log('드롭된 파일:', files[0].name);
});
요소 간 드래그 앤 드롭
// 드래그 가능한 요소
const draggableItem = document.getElementById('draggable');
draggableItem.draggable = true;
draggableItem.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', '드래그된 데이터');
});
// 드롭 영역
const dropZone = document.getElementById('dropZone');
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
const data = e.dataTransfer.getData('text/plain');
dropZone.textContent = `받은 데이터: ${data}`;
});
핵심 포인트: preventDefault()를 반드시 호출해야 하고, dataTransfer 객체를 통해 데이터를 주고받을 수 있습니다.
📝 Blob
Blob(Binary Large Object)은 파일과 같은 바이너리 데이터를 다루는 객체입니다.
파일 다운로드, 이미지 처리, 데이터 저장 등에 활용됩니다.
기본 사용법
// 텍스트로 Blob 생성
const textBlob = new Blob(['안녕하세요!'], { type: 'text/plain' });
console.log(textBlob.size); // 바이트 크기
console.log(textBlob.type); // MIME 타입
// JSON 데이터로 Blob 생성
const data = { name: '홍길동', age: 25 };
const jsonBlob = new Blob([JSON.stringify(data)], { type: 'application/json' });
파일 다운로드 구현
function downloadFile(content, filename) {
const blob = new Blob([content], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
// 메모리 정리
URL.revokeObjectURL(url);
}
// 사용 예시
downloadFile('다운로드할 내용입니다.', 'sample.txt');
이미지 미리보기
const fileInput = document.getElementById('fileInput');
const preview = document.getElementById('preview');
fileInput.addEventListener('change', (e) => {
const file = e.target.files[0];
if (file && file.type.startsWith('image/')) {
const imageUrl = URL.createObjectURL(file);
preview.src = imageUrl;
// 메모리 정리 (이미지 로드 후)
preview.onload = () => URL.revokeObjectURL(imageUrl);
}
});
핵심 포인트: URL.createObjectURL()로 임시 URL을 생성하고, 사용 후에는 revokeObjectURL()로 메모리를 정리해야 합니다.
📝 Web Workers
Web Workers는 메인 스레드를 블로킹하지 않고 백그라운드에서 스크립트를 실행할 수 있게 해주는 기술입니다.
무거운 계산이나 데이터 처리에 유용합니다.
기본 구현
worker.js 파일:
// 메시지 받기
self.addEventListener('message', (e) => {
const { numbers } = e.data;
// 무거운 계산 (배열 합계)
let sum = 0;
for (let i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
// 결과 전송
self.postMessage({ result: sum });
});
메인 스크립트:
const worker = new Worker('worker.js');
// 워커에게 작업 요청
const largeArray = Array.from({ length: 1000000 }, (_, i) => i + 1);
worker.postMessage({ numbers: largeArray });
// 결과 받기
worker.addEventListener('message', (e) => {
console.log('계산 결과:', e.data.result);
worker.terminate(); // 워커 종료
});
// 에러 처리
worker.addEventListener('error', (e) => {
console.error('워커 에러:', e.message);
});
인라인 워커 (파일 없이 사용)
function createInlineWorker(workerFunction) {
const blob = new Blob([`(${workerFunction.toString()})()`],
{ type: 'application/javascript' });
return new Worker(URL.createObjectURL(blob));
}
// 워커 함수 정의
function workerCode() {
self.addEventListener('message', (e) => {
const { start, end } = e.data;
let result = 0;
for (let i = start; i <= end; i++) {
result += i * i; // 제곱의 합
}
self.postMessage({ result });
});
}
// 사용
const worker = createInlineWorker(workerCode);
worker.postMessage({ start: 1, end: 10000 });
worker.addEventListener('message', (e) => {
console.log('제곱합:', e.data.result);
});
핵심 포인트: 워커는 DOM에 직접 접근할 수 없고, postMessage()를 통해서만 데이터를 주고받을 수 있습니다.
📝 실전 활용 예시
세 가지 API를 조합한 파일 처리 시스템:
// 드래그 앤 드롭으로 파일 받기
dropArea.addEventListener('drop', (e) => {
e.preventDefault();
const file = e.dataTransfer.files[0];
if (file) {
processFileInWorker(file);
}
});
function processFileInWorker(file) {
const worker = new Worker('fileProcessor.js');
// 파일을 ArrayBuffer로 읽기
file.arrayBuffer().then(buffer => {
worker.postMessage({ buffer, filename: file.name });
});
worker.addEventListener('message', (e) => {
const { processedData } = e.data;
// 처리된 데이터로 새 파일 생성
const resultBlob = new Blob([processedData], { type: 'text/plain' });
downloadFile(resultBlob, 'processed_' + file.name);
worker.terminate();
});
}
📚 마무리 정리
오늘 배운 API들을 정리하면:
드래그 앤 드롭 API: 사용자 친화적인 파일 업로드와 요소 조작이 가능합니다. preventDefault()와 dataTransfer 객체가 핵심입니다.
Blob: 바이너리 데이터를 다루며, 파일 다운로드와 이미지 처리에 활용됩니다. 메모리 관리를 위해 revokeObjectURL()을 잊지 말아야 합니다.
Web Workers: 메인 스레드를 블로킹하지 않고 백그라운드에서 무거운 작업을 처리합니다. DOM 접근이 불가능하고 메시지 기반 통신만 가능합니다.
💡 오늘 새롭게 알게 된 것
- 드래그 앤 드롭에서 dragover 이벤트에 preventDefault()를 호출해야 드롭이 가능해진다는 점입니다.
- Blob 객체로 메모리상의 데이터를 파일처럼 다룰 수 있다는 점입니다.
- Web Workers가 완전히 독립된 환경에서 실행되어 DOM 접근이 안 된다는 점입니다.
🤔 어려웠던 점
- 드래그 앤 드롭의 여러 이벤트들(dragover, dragleave, drop)을 조합하는 것입니다.
- Web Workers에서 메인 스레드와 데이터를 주고받는 메커니즘 이해하는 것입니다.
- Blob과 URL.createObjectURL()의 메모리 관리 개념입니다.
🎯 다음 학습 계획
모던 자바스크립트 입문 시리즈가 완료되었습니다!
그동안 함께해 주셔서 감사합니다.
앞으로는 지금까지 배운 내용을 토대로 더욱 중요하고 깊이 있는 자바스크립트 주제들을 다뤄보겠습니다.
'Development > Javascript' 카테고리의 다른 글
[JS] undefined와 null의 차이점 (1) | 2025.07.16 |
---|---|
[JS] this 키워드 (3) | 2025.07.10 |
모던 자바스크립트 입문 - Chapter 18: 생성자와 클래스 구문 💻 (1) | 2025.07.04 |
모던 자바스크립트 입문 - Chapter 17: MVC 모델에 기반을 둔 프로그램 설계 💻 (0) | 2025.07.03 |
모던 자바스크립트 입문 - Chapter 16: HTTP 제어 (Ajax) 💻 (1) | 2025.07.02 |