올바른 이해와 사용 방법
브라우저의 방문 기록(Session History)에서 "뒤로 가기" 또는 "앞으로 가기"로 이동할 때 popstate 이벤트가 발생합니다.
window 객체에서 발생하는 이벤트입니다.
구문
window.addEventListener("popstate", (event) => { })
window.onpopstate = (event) => { }
방문 기록이 변경될 때 발생하는 popstate 이벤트
브라우저의 방문 기록(Session History)이 변경되어 이전 페이지 또는 다음 페이지로 이동할 때, 즉 현재 표시되고 있는 방문 기록 항목(현재 활성화된 항목)이 다른 항목으로 전환된 후 발생하는 이벤트가 popstate 이벤트입니다.
브라우저의 방문 기록(Session History)에 새로운 방문 기록을 추가할 때에는 popstate 이벤트가 발생하지 않습니다. 즉, 기존에 있던 방문 기록 항목(entry) 사이를 오갈 때 발생합니다.
popstate 이벤트는 다음과 같은 상황에서 발생합니다.
- 사용자가 브라우저의 "뒤로 가기" 버튼을 눌렀을 때
- 사용자가 브라우저의 "앞으로 가기" 버튼을 눌렀을 때
history.go()메서드를 사용해 실제 특정 방문 기록으로 이동했을 때
(단,history.go(0)으로 현재 페이지로 이동하거나, 지정한 특정 방문 기록이 브라우저의 현재 방문 기록에 없을 경우는 제외)history.back()메서드를 사용해 이전 페이지로 이동했을 때
(단, 브라우저의 현재 방문 기록에 이전 페이지 기록이 없는 경우는 제외)history.forward()메서드를 사용해 다음 페이지로 이동했을 때
(단, 브라우저의 현재 방문 기록에 다음 페이지 기록이 없는 경우는 제외)
주의: 이럴 때는 발생하지 않습니다!
- 브라우저의 방문 기록(Session History)에 새로운 방문 기록을 추가할 때
(예:<a>요소를 통한 이동,<form>제출 등 HTML로 이동하는 경우, JavaScript를 사용한 새로운 페이지로 이동, 서버 사이드 언어를 사용한 HTTP Header 리다이렉트 등) - 사용자가 브라우저의 "새로고침" 버튼을 눌렀을 때
history.pushState()메서드를 사용해 표시되는 URL이 바뀔 때history.replaceState()메서드를 사용해 표시되는 URL이 바뀔 때- 그 밖에 JavaScript를 사용해 현재 페이지를 새로고침했을 때
기본 예제
// popstate 이벤트 리스너 등록
window.addEventListener("popstate", (event) => {
console.log("현재 활성화된 방문 기록이 변경되었습니다.");
// 현재 활성화된 방문 기록에 저장된 상태(State) 데이터가 있으면 출력
if (event.state) {
console.log("저장된 상태 데이터:", event.state);
}
});
위 예제 코드는 popstate 이벤트를 window.addEventListener() 메서드로 이벤트 리스너에 등록하는 아주 전형적인 방법 중 하나입니다.
주목하세요!
popstate 이벤트는 발생 시 이벤트 객체의 state 속성으로 현재 활성화된 방문 기록 항목(entry)의 상태(State) 데이터를 함께 가지고 있다는 특징이 있습니다. 위 코드 예제의 event.state가 이에 해당합니다.
popstate 이벤트의 state 속성
popstate 이벤트의 state 속성은 popstate 이벤트가 발생했을 때 현재 활성화된 방문 기록 항목(entry)의 상태(State) 데이터를 반환합니다. 이 속성은 읽기 전용입니다.
popstate 이벤트는 브라우저의 방문 기록을 이동할 때 발생하는 이벤트이므로, 현재 활성화된 방문 기록 항목의 상태(State) 데이터를 이벤트 객체의 state 속성으로 바로 가져와 사용할 수 있어 직관적으로 활용할 수 있습니다.
popstate 이벤트의 state 속성으로 반환되는 상태(State) 데이터는 현재 활성화된 방문 기록 항목(entry)에 history.pushState() 또는 history.replaceState() 메서드를 사용해 저장한 데이터입니다.
만약 현재 활성화된 방문 기록 항목에 저장된 상태(State) 데이터가 없다면 null을 반환합니다.
활용 예제
사용자가 브라우저의 '뒤로 가기' 버튼을 눌러 이전에 방문했던 페이지로 돌아왔다고 가정합니다.
이 페이지에는 여러 탭으로 콘텐츠를 구분하여 보여주고 있으며, 사용자가 마지막으로 선택한 탭 정보는 이미 history.pushState() 메서드를 사용해 방문 기록의 상태(State) 데이터로 저장해 두었습니다. 사용자가 이 페이지로 다시 돌아왔을 때는 여러 탭 중 이전에 선택했던 탭을 다시 보여주는 것이 UX(User Experience, 사용자 경험) 측면에서 더 좋을 수 있습니다.
아래 예제는 popstate 이벤트를 활용해 사용자가 이 페이지로 다시 돌아왔을 때 저장된 탭 정보를 읽어 이전에 선택했던 탭을 복원하는 예제입니다.
// 탭 전환 함수
function selectTab(tabName, shouldPushState = true) {
console.log(`현재 활성화된 탭: ${tabName}`);
// (실제 화면에서는 이곳에서 탭 콘텐츠를 보여주는 로직이 실행됩니다.)
// 새로운 방문 기록 항목을 추가하면서 상태 데이터({ tab: tabName })를 저장합니다.
if (shouldPushState) {
history.pushState({ tab: tabName }, "", `?tab=${tabName}`);
}
}
// 브라우저의 방문 기록이 변경되면(뒤로 가기/앞으로 가기) 이전 탭을 복원합니다.
window.addEventListener("popstate", (event) => {
let tabToRestore = null;
// 1. 방문 기록에 저장된 상태(State) 데이터가 있는지 확인합니다.
if (event.state) {
tabToRestore = event.state.tab; // 저장된 탭 이름 가져오기
} else {
tabToRestore = "home"; // 저장된 데이터가 없다면 기본값인 'home'으로 설정
}
console.log(`복원할 탭: ${tabToRestore}`);
// 2. 방문 기록을 새로 추가하지 않고(false), 화면만 이전 탭으로 복원합니다.
selectTab(tabToRestore, false);
});
명세서
| 명세서 사양 | |
|---|---|
popstate
|
HTML #event-popstate |
onpopstate
|
HTML #handler-window-onpopstate |
state
|
HTML #dom-popstateevent-state-dev |
브라우저 호환성
| 이벤트 |
데스크탑 Chrome
|
데스크탑 Edge
|
데스크탑 Firefox
|
Safari
|
|---|---|---|---|---|
popstate
|
5 | 12 | 4 | 5 |
state
|
5 | 12 | 4 | 6 |