올바른 이해와 사용 방법
브라우저는 현재 페이지의 URL 해시(프래그먼트)가 변경되면 hashchange 이벤트를 발생시킵니다.
window 객체에서 발생하는 이벤트입니다.
구문
window.addEventListener("hashchange", (event) => { })
window.onhashchange = (event) => { }
hashchange 이벤트는 다음과 같은 상황에서 발생합니다.
- 사용자가 브라우저의 "뒤로 가기" 버튼을 눌러 해시(프래그먼트)가 변경된 페이지로 이동했을 때
- 사용자가 브라우저의 "앞으로 가기" 버튼을 눌러 해시(프래그먼트)가 변경된 페이지로 이동했을 때
- 브라우저의 URL에 해시가 변경될 때
[예:<a>요소나,<form>제출 등 HTML로 해시(프래그먼트) 링크로 이동하는 경우, JavaScript를 사용한 해시(프래그먼트) 설정, 서버 사이드 언어를 사용한 해시(프래그먼트) 링크가 포함된 HTTP Header 리다이렉트 등] - 이러한 상황들에서 변경된 해시 값(프래그먼트 식별자)이 현재 문서에 존재하는 요소의
id를 찾지 못하더라도(없거나, 일치하지 않더라도) 발생합니다.
주의: 이럴 때는 발생하지 않습니다!
- 현재 페이지의 URL 해시(프래그먼트)가 변경되지 않았을 때
[현재page.html#section1인데 다시#section1으로 이동하려는 경우, 이전 상태 해시(프래그먼트)와 동일하므로 이벤트가 발생하지 않습니다.] - 사용자가 브라우저의 "새로고침" 버튼을 눌렀을 때
window.history.pushState()메서드를 사용해 표시되는 URL이 바뀔 때
[URL 해시(프래그먼트)가 변경되더라도hashchange이벤트는 발생하지 않습니다.]window.history.replaceState()메서드를 사용해 표시되는 URL이 바뀔 때
[URL 해시(프래그먼트)가 변경되더라도hashchange이벤트는 발생하지 않습니다.]- 현재 URL에서 해시(프래그먼트)가 아닌 다른 경로(Path)나 쿼리 스트링(Query String)이 변경될 때
- 새 문서로 로드했을 때
[사용자가 해시(프래그먼트)가 포함된 즐겨찾기(북마크)나 URL을 직접 입력하여 페이지에 접근할 때 등]
기본 예제
// 해시가 변경될 때마다 현재 해시 값을 콘솔에 출력합니다.
window.addEventListener("hashchange", (event) => {
console.log("해시가 변경되었습니다.");
console.log("현재 해시 값:", location.hash);
});
코드 부연설명
location.hash 속성은 현재 URL의 해시(# 포함) 정보를 문자열로 반환합니다. 해시가 없으면 빈 문자열("")을 반환합니다.
자바스크립트 현재 URL 해시(프래그먼트) 가져오기를 참조하세요!
활용 예제
URL의 해시를 활용하면 별도의 복잡한 라이브러리 없이도 특정 섹션으로 이동할 때 원하는 동작을 수행할 수 있습니다. 다음 예제에서는 캔버스를 포함하고 있는 특정 섹션으로 이동하면 원을 그리는 기능을 구현해 보겠습니다.
<nav>
<a href="#general-section">일반 섹션</a>
<a href="#canvas-section">캔버스 섹션</a>
</nav>
<section id="general-section">
<h2>일반 섹션</h2>
</section>
<section id="canvas-section">
<h2>캔버스 섹션</h2>
<canvas id="my-canvas" width="250" height="180"></canvas>
</section>
window.addEventListener("hashchange", () => {
if (location.hash === "#canvas-section") {
// 캔버스 그리기
const canvas = document.getElementById("my-canvas");
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(125, 90, 50, 0, Math.PI * 2);
ctx.fill();
}
});
명세서
| 명세서 사양 | |
|---|---|
hashchange
|
HTML #event-hashchange |
onhashchange
|
HTML #handler-window-onhashchange |
브라우저 호환성
| 이벤트 |
데스크탑 Chrome
|
데스크탑 Edge
|
데스크탑 Firefox
|
Safari
|
|---|---|---|---|---|
hashchange
|
8 | 12 | 3.6 | 5 |