onload와 onerror의 역할
- onload: 리소스가 성공적으로 로드되고(그리고 실행까지 완료된 후) 발생합니다.
- onerror: 리소스 로딩 중 문제(네트워크 실패, 잘못된 URL 등)가 발생했을 때 트리거됩니다.
동적 스크립트 로딩과 상태 감지
외부 스크립트를 동적으로 추가하고, 로딩이 완료된 후 해당 스크립트 내에 정의된 함수를 호출해야 하는 경우가 있습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>스크립트 로딩 감지</title>
<style>
#loadStatus { color: #555; margin-bottom: 10px; }
#actionBtn { padding: 8px 16px; background: #4caf50; color: white; border: none; }
#actionBtn:disabled { background: #ccc; cursor: not-allowed; }
</style>
</head>
<body>
<div id="loadStatus">라이브러리 로딩 중...</div>
<button id="actionBtn" disabled>기능 실행</button>
<script>
const status = document.getElementById('loadStatus');
const actionBtn = document.getElementById('actionBtn');
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js';
script.onload = () => {
status.textContent = 'Axios 라이브러리 로드 완료!';
actionBtn.disabled = false;
actionBtn.addEventListener('click', () => {
axios.get('https://api.example.com/data')
.then(response => alert('데이터 로드 성공!'))
.catch(err => alert('데이터 요청 실패'));
});
};
script.onerror = () => {
status.textContent = '스크립트 로드 실패';
actionBtn.textContent = '오류 발생';
actionBtn.disabled = true;
};
document.head.appendChild(script);
</script>
</body>
</html>
- onload: Axios 로드 후 버튼 활성화 및 API 요청 가능
- onerror: 로드 실패 시 사용자 알림 및 버튼 비활성화
이미지 로딩 상태 관리
이미지 리소스도 onload와 onerror 이벤트를 지원하여 로딩 상태 추적을 할 수 있습니다. 새 Image 객체를 생성해 이미지 로딩 상태를 감지한 후, 로드된 이미지를 페이지에 삽입하거나 에러를 알리는 방식입니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>이미지 로딩 추적</title>
<style>
#gallery { border: 1px solid #ddd; padding: 10px; min-height: 100px; }
#imgStatus { font-size: 14px; color: #777; }
</style>
</head>
<body>
<div id="gallery"></div>
<div id="imgStatus">이미지 로딩 중...</div>
<script>
const gallery = document.getElementById('gallery');
const imgStatus = document.getElementById('imgStatus');
const img = new Image();
img.src = 'https://picsum.photos/300';
img.onload = () => {
gallery.appendChild(img);
imgStatus.textContent = '이미지 로드 완료!';
};
img.onerror = () => {
imgStatus.textContent = '이미지 로드 실패';
const fallback = new Image();
fallback.src = 'fallback.jpg'; // 대체 이미지
gallery.appendChild(fallback);
};
</script>
</body>
</html>
- onload: 이미지가 성공적으로 로드 완료
- onerror: 실패 시 상태 표시 및 대체 이미지 삽입
CORS와 오류 처리
브라우저 보안 정책 때문에, 다른 도메인에서 로드한 스크립트나 리소스에서 에러가 발생하면 구체적인 에러 정보를 얻기 어려울 수 있습니다. 예를 들어, 동일 출처가 아닌 리소스에서 발생한 스크립트 에러는 "Script error."라는 간단한 메시지로만 전달됩니다. 이를 해결하기 위해서는 서버에서 Access-Control-Allow-Origin 헤더를 제공한다면, 스크립트 태그에 crossorigin 속성을 추가하여 더 자세한 오류 정보를 얻을 수 있습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>CORS 리소스 오류 처리</title>
</head>
<body>
<h1>CORS 스크립트 로드</h1>
<div id="errorLog"></div>
<script>
const errorLog = document.getElementById('errorLog');
window.onerror = (msg, url, line, col, error) => {
errorLog.textContent = `에러: ${msg}, URL: ${url}, 위치: ${line}:${col}`;
};
const script = document.createElement('script');
script.crossorigin = 'anonymous';
script.src = 'https://api.example.com/nonexistent.js';
script.onload = () => {
errorLog.textContent = '스크립트 로드 성공';
};
script.onerror = () => {
errorLog.textContent = '스크립트 로드 실패 (세부 정보는 window.onerror 확인)';
};
document.head.appendChild(script);
</script>
</body>
</html>
예제: Promise 기반 다중 리소스 로딩
function loadResource(type, src) {
return new Promise((resolve, reject) => {
const element = document.createElement(type);
element.src = src;
element.onload = () => resolve(element);
element.onerror = () => reject(new Error(`로드 실패: ${src}`));
document.head.appendChild(element);
});
}
Promise.all([
loadResource('script', 'https://cdn.example.com/lib1.js'),
loadResource('script', 'https://cdn.example.com/lib2.js')
])
.then(() => console.log('모든 스크립트 로드 완료'))
.catch(err => console.error(err));
'브라우저' 카테고리의 다른 글
Selection과 Range API로 텍스트 선택 및 조작하기 (0) | 2025.02.21 |
---|---|
MutationObserver로 DOM 변화 실시간 제어하기 (0) | 2025.02.21 |
defer와 async로 최적화된 스크립트 로딩 (0) | 2025.02.21 |
HTML 문서 생명주기 (0) | 2025.02.21 |
폼 전송하기: submit 이벤트 (1) | 2025.02.21 |