브라우저에서 페이지 로딩을 하면, 세션 히스토리를 갖는다. 브라우저는 이 히스토리를 stack으로 관리한다.
세션 히스토리는 페이지를 이동할 때마다 쌓이며, 이를 통해 뒤로 가기 또는 앞으로 가기 같은 이동이 가능하다.
=> 즉, "어떤 페이지를 탐색했는지에 대해서 history를 쌓는 것" 이라고 생각하면 된다.
pushState, replace 두 개의 함수로 화면 이동 없이 현재 URL을 업데이트 할 수 있다.
실제로는 화면 이동이 일어나지 않지만, 히스토리에는 쌓이고, 현재 url을 바꿔줄 수 있는 것이다.
=> 이를 이용해 페이지 이동을 하지 않고 화면을 다시 그릴 수 있다.
=> 이러한 특성 때문에 세션 history를 이용해 SPA를 구현하는 것이 가능하다 !
hashbang 방식으로 만들었던 url을 다음과 같이 바꿔줄 수 있다
/
=> HomePage
/list
=> ListPage
/detail/1
=> DetailPage
=> 훨씬 보기 편하고 직관적이다 !
=> "url을 따라서 다른 화면을 그린다" 는 측면에서 보면 좀 더 자연스러운 방식이라고도 말할 수 있다.
console 창에 history
를 입력해보면 현재 페이지에 대한 History
정보를 확인할 수 있다.
length
현재 페이지까지 쌓여있는 history가 몇 개인지를 나타낸다. 현재는 총 13개의 히스토리가 앞에 있는 것.
scrollRestoration
뒤로 가기 시, 이전에 있던 scroll로 돌아가도록 할 것인지를 나타낸다.
state
history의 state로, pushState와 replaceState 함수의 첫번째 인자로 전달한 값이 여기에 저장된다.
history.pushState(state, title, url)
state
history.state
에서 꺼내 쓸 수 있는 값이다.
title
변경될 페이지의 title을 가리키는 값인 것 같지만, 거의 대부분의 브라우저에서 지원하지 않는다. 따라서 주로, 빈 string ""
을 넣는다.
url
세션 히스토리에 새로 넣을 url 값이다.
a 태그를 클릭하거나 location.href
로 url을 변경하는 것과는 다르게 이 url이 변경된다고 해서 화면이 리로드 되거나 그러진 않는다.
history.replaceState(state, title, url)
각 파라미터의 역할은 pushState
과 같다. 다만, replaceState는 세션 히스토리에 새 url 상태를 쌓지 않고, 현재 url을 대체한다.
ex) 게시글 작성 페이지에서 글을 쓰고 완료버튼을 누르고, 작성 완료 페이지로 이동할 때 pushState를 실행한다면, 작성 완료 페이지에서 뒤로 가기를 누르면 다시 작성 페이지으로 이동하게 될 것이다. 이는 우리가 원하는 상황이 아닐 수 있다.
=> 이렇게 뒤로가기를 제한시켜야 하는 상황이 있거나 할 때, replaceState를 사용하면, 게시물을 작성 => 작성 완료 페이지의 url로 replace => 여기서 뒤로가기를 눌러도 작성 화면으로 이동할 수 없게 된다.
console 창에서 메서드들을 실행해보며 실제 history가 어떻게 변화하는지 확인해보자.
console 창에 pushState를 실행시켜 보면, 화면의 이동 없이 정말 url이 바뀐 것을 볼 수 있다.
=> SPA는 이러한 history의 특성에 많은 부분 기반하고 있다.
console에서 pushState을 통해 history에 새 url state를 쌓을 수 있다.
=> 위에서 3번의 pushState 후에 history의 length가 1 => 4로 증가한 것을 볼 수 있다.
replaceState를 통해 새로운 state를 쌓는 것이 아닌, 현재 state의 url을 다른 값으로 바꾼다.
=> /mail/new
에서 /mail/5
로 url이 바뀐 후, 뒤로 가기를 누르면 /mail/4
url로 이동하는 것을 확인할 수 있다.
특정 state에서 history.back()
, history.forward()
, history.go()
를 실행하거나 뒤로가기 버튼, 앞으로 가기 버튼을 누르하면, history내 특정 state로 이동할 수 있고, 이 때 popstate라는 이벤트가 발생한다.
history.back()
위의 코드는 사용자가 브라우저 도구 모음의 뒤로 가기 버튼을 누른 것과 같은 동작을 한다. 즉, 현재 state에서 하위 state로 이동한다. 하지만 현재 state를 pop하지는 않는다. 따라서, history의 length는 그대로 유지된다.
history.forward()
위의 코드는 사용자가 브라우저 도구 모음의 앞으로 가기 버튼을 누른 것과 같은 동작을 한다. 현재 state에서 상위 state로 이동한다. 역시 현재 state를 pop 하지는 않는다. history의 length는 유지된다.
history.go()
go()
메서드를 사용하면 세션 기록에서 현재 페이지의 위치를 기준으로, 상대적인 거리에 위치한 특정 state까지 이동할 수 있습니다.
history.go(-1); // 한 state 전으로 이동
history.go(1); // 한 state 앞으로 이동 => 현재 state서 2칸 위에 있는 state로 이동
history.go(0) // 새로고침
history.go() // 새로고침
history.go(0)
go()
메서드에 인자를 넣지 않거나 0을 넣으면 브라우저 도구 모음의 새로고침 버튼을 누른 것과 같이 동작한다.
브라우저에서 페이지를 이동하게되면 popstate
라는 이벤트가 발생한다. 뒤로가기, 앞으로가기, 새로고침 버튼, `history.back()
, history.forward()
, history.go()
을 실행하면 popstate
이벤트가 발생한다.
하지만, pushState
, replaceState
를 실행했을 때는 popstate
이벤트가 발생하지 않는다.
popstate
이벤트 발생 시, console로 "popstate ! "
를 출력하도록 해보면 이를 확인할 수 있다.
window.addEventListener("popstate", function () {]
console.log("popstate ! ", history.state);
});
딱 history API 강의 들을 차례였는데 덕분에 수월하게 들을 수 있을 거 같아요!