
SPA(Single Page Application): 초기 로딩 후 페이지 전체를 새로고침하지 않고 동적으로 콘텐츠를 갱신하는 웹 애플리케이션
장점: 빠른 응답성과 효율적인 네트워크 사용으로 매끄러운 사용자 경험 제공
SPA는 필요한 데이터만 받아와 화면을 갱신하며, 주로 자바스크립트와 history API를 활용하여 구현
SPA 구현 시 자바스크립트의 history API를 활용하여 브라우저 히스토리 제어 가능
history.pushState()와 popstate 이벤트는 사용자의 페이지 이동 시 URL 동적 변경 및 뒤로 가기, 앞으로 가기 기능 구현에 중요한 역할을 함
History API는 브라우저 히스토리 제어를 위한 자바스크립트 기능 제공history.pushState() 메서드로 SPA에서 URL과 상태를 동적 변경. 주소 표시줄은 변경되지만 페이지는 새로고침되지 않아 동적 콘텐츠 갱신과 URL 업데이트를 동시에 처리 가능history.pushState(state, title, url) 메서드의 주요 매개변수
history.pushState()를 이용해 SPA에서 상태 추가 및 URL 변경 예시:
// 새 상태를 히스토리에 추가
window.history.pushState({page: 2}, "", "/page2");
window.addEventListener('popstate', function(event) {
const page = event.state?.page || 'home';
updateContent(page);
});
function updateContent(page) {
document.getElementById('content').innerHTML = pages[page];
}
사용자의 뒤로가기 클릭 시, popstate 이벤트 핸들러에서 event.state를 통해 객체 접근 가능
event.state
// 뒤로가기, 앞으로 가기 이벤트 처리
window.addEventListener('popstate', function(event) {
console.dir(event.state) //{page: 2}
});
console.dir(event)로 popstate 이벤트 객체의 상세 정보 확인 가능
객체 내 state 속성은 pushState() 또는 replaceState() 메서드로 전달된 상태 객체임
상태 객체 활용으로 페이지 전환 시 필요 데이터 저장 및 복원 가능, SPA에서 더 풍부한 네비게이션 경험 제공 가능함
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SPA Example</title>
</head>
<body>
<ul>
<li><a href="/" data-url="home">Home</a></li>
<li><a href="/about" data-url="about">About</a></li>
<li><a href="/contact" data-url="contact">Contact</a></li>
</ul>
<div id="page">Home 페이지입니다.</div>
<script>
// SPA 페이지 콘텐츠 정의
const pages = {
home: "Home 페이지입니다.",
about: "About 페이지입니다.",
contact: "Contact 페이지입니다. <input text='text' placeholder='연락처 입력 하세요' />",
};
// 각 링크에 이벤트 핸들러 추가
const aEls = document.querySelectorAll("a");
aEls.forEach((aEl) =>
aEl.addEventListener("click", function (e) {
e.preventDefault(); // 링크의 기본 동작 방지
const page = e.currentTarget.dataset.url;
// 클릭한 링크의 페이지 정보 가져오기
history.pushState({ page: page }, "", `/${page}`);
// URL과 상태를 히스토리에 추가
document.getElementById("page").innerHTML = pages[page];
// 페이지 콘텐츠 업데이트
})
);
// 뒤로가기, 앞으로 가기 이벤트 처리
window.addEventListener("popstate", function (event) {
const page = event.state?.page || "home";
// 상태가 없으면 기본 페이지로 설정(예외처리)
document.getElementById("page").innerHTML = pages[page];
// 이전 상태에 맞는 콘텐츠 렌더링
});
</script>
</body>
</html>
pages 객체에 페이지별로 표시할 콘텐츠 정의. 각 페이지에 맞는 텍스트나 HTML을 미리 설정하여 링크 클릭 시 innerHTML을 이용해 해당 내용 표시 가능click 이벤트 핸들러 추가하여 클릭 시 다음 작업 수행e.preventDefault(): 페이지 이동을 막고 자바스크립트로 전환 처리e.currentTarget.dataset.url: 클릭한 링크의 data-url 속성에서 페이지 정보 가져옴history.pushState(): URL 변경 및 새로운 상태를 브라우저의 히스토리에 저장document.getElementById("page").innerHTML: pages 객체를 이용해 page div의 콘텐츠 업데이트popstate 이벤트는 사용자가 브라우저의 뒤로가기나 앞으로가기를 누를 때 발생event.state: pushState를 통해 저장된 상태 가져옴. 페이지 이동 시 state 객체에 저장된 정보를 활용하여 콘텐츠 복원 가능document.getElementById("page").innerHTML: 가져온 state에 따라 page div의 콘텐츠 업데이트history.back(): 현재 URL에서 한 단계 뒤로 이동history.forward(): 현재 URL에서 한 단계 앞으로 이동history.go(n): n이 양수면 앞으로, 음수면 뒤로 이동. 예: history.go(-2)는 두 단계 뒤로 이동출처: 수코딩