바닐라 자바스크립트를 이용하여 SPA를 위한 간단한 Router를 만들어보고, 관련 개념을 정리하자.
데모페이지와 코드샌드박스 소스코드 주소는 아래와 같다.
// index.html
<!DOCTYPE html>
<html>
<head>
<title>SPA Router - Vanila JavaScript</title>
<meta charset="UTF-8" />
</head>
<body>
<div id="root">
<nav>
<a href="/" id="homeRoute">Home</a>
<a href="/about" id="aboutRoute">About</a>
<a href="/blog" id="blogRoute">Blog</a>
</nav>
<div id="contents"></div>
</div>
<script src="router.js"></script>
</body>
</html>
routes
객체를 만든다. getRouteHtml
함수를 만들었고 이 함수는 fetch를 통해 받은 response의 text()를 DOM에 삽입한다.handleRoute
함수는 앵커태그 클릭 시 호출된다. 앵커의 href값을 history.pushState 메서드의 세 번째 인수(url)에 전달하여 브라우저의 URL을 업데이트한다.// route.js
const routes = {
404: "/pages/404.html",
"/": "/pages/index.html",
"/about": "/pages/about.html",
"/blog": "/pages/blog.html",
};
const getRouteHtml = async () => {
const path = window.location.pathname;
const route = routes[path] || routes[404];
const $contents = document.getElementById("contents");
await fetch(route)
.then(response => {
return response.text();
})
.then(text => {
$contents.innerHTML = text;
});
};
const handleRoute = event => {
event = event || window.event;
event.preventDefault(); // anchor 태그의 기본동작인 링크 대상으로 이동하는 행동을 방지한다.
window.history.pushState({}, "", event.target.href);
getRouteHtml();
};
window.onpopstate = getRouteHtml;
getRouteHtml();
document.getElementById("homeRoute").addEventListener("click", handleRoute);
document.getElementById("aboutRoute").addEventListener("click", handleRoute);
document.getElementById("blogRoute").addEventListener("click", handleRoute);
String
으로 Resolve되는 Promise를 반환한다(UTF-8로 디코딩됨).Location 객체
를 얻어올 수 있다. 이는 현재 도큐먼트의 로케이션에 대한 정보를 담고 있다.location.pathname
은 '/' 문자 뒤 URL의 경로를 값으로 하는 DOMString이다.세션 기록
, 즉 현재 페이지를 불러온 탭 또는 프레임의 방문 기록을 조작할 수 있는 방법을 제공한다.back()
, forward()
, go()
, pushState()
, replaceState()
가 있다.history.pushState()
는 브라우저의 세션 기록 스택에 상태를 추가한다.history.pushState(state, title[, url]);
state
: 새로운 세션 기록 항목에 연결할 상태 객체. 사용자가 새로운 상태로 이동할 때마다 popstate 이벤트가 발생하는데, 이 때 이벤트 객체의 state 속성에 해당 상태의 복제본이 담겨 있다. title
: (현재 대부분의 브라우저가 무시) 그냥 빈 문자열 지정url
: 새로운 세션 기록 항목의 URL. 상대 URL을 지정할 수 있으며, 이 땐 현재 URL을 기준으로 사용합니다.popstate
두 히스토리 엔트리 간의 이동
이 있을 때만 발생한다.엔트리
가 history.pushState() 메서드나 history.replaceState() 메서드에 의해 생성되면, popstate 이벤트의 state 속성
은 히스토리 엔트리 state 객체
의 복사본을 갖게 됩니다.WindowEventHandlers.onpopstate
: window의 popstate 이벤트 핸들러window.onpopstate = funcRef;