본문 바로가기

JavaScript

History

히스토리란 페이지 이동 정보를 브라우저가 기록한 것으로 객체 형식으로 저장됩니다.

 

히스토리 객체의 속성과 정보를 관리하는 메서드는 아래와 같습니다.

 

 

속성
  • length : 등록된 히스토리의 개수의 정보를 담고 있습니다.(페이지를 몇 번에 거쳐 이동한 지에 대한 정보)
  • scrollRestoration : 앞이나 뒤로 이동할 때 스크롤 위치의 복원 여부 정보를 담고 있으며 지정이 가능합니다.
  • state : 현재 히스토리에 등록된 데이터(state)의 정보를 담고 있습니다.

 

 

메서드
  • back : 히스토리 뒤로 가기
  • forward : 히스토리 앞으로 가기
  • go : 현재 페이지 기준 인수로 전달받는 특정 히스토리 위치로 이동 (뒤로 두 번 이동을 예로 들면 -2 인수로 전달)

 

  • pushState : 첫 번째 인자로 상태, 두 번째 인자로 제목, 세 번째 인자로 주소를 전달하여 히스토리에 상태 및 주소를 추가합니다.(pushState 메서드의 경우 페이지를 새로 고침 하지 않고 새로운 히스토리를 추가합니다.)

 

  • replaceState : 첫 번째 인자로 상태, 두 번째 인자로 제목, 세 번째 인자로 주소를 전달하여 현재 히스토리의 상태 및 주소를 교체합니다. (교체되기 전의 히스토리는 제거됩니다.)

*모든 브라우저(Safari 브라우저 제외)는 "제목" 옵션을 무시하기 때문에 빈 문자열로 인수를 전달해도 됩니다.

 

 

 

 


위의 내용의 간단한 내용과 함께 살펴보도록 하겠습니다.

 

HTML 마크업
<body>
    <nav>
      <a href="#/page1">p1</a>
      <a href="#/page2">p2</a>
      <a href="#/page3">p3</a>
      <input type="text" />
    </nav>

    <div id="app">
      <section id="/page1" class="page1">
        <h1>Page 1</h1>
      </section>

      <section id="/page2" class="page2">
        <h1>Page 2</h1>
      </section>

      <section id="/page3" class="page3">
        <h1>Page 3</h1>
      </section>
    </div>
  </body>

 

 

p1이라는 a태그 클릭 시 주소 뒤에 해쉬로 시작하는 추가적인 주소가 붙은 것을 확인할 수 있습니다. (p2, p3 클릭도 속성에 등록한 해쉬가 주소 뒤에 붙는 것을 확인할 수 있습니다.)

 

 

만약 #/page1 -> #/page2 -> #/page3으로 페이지 내부 이동 후 뒤로 가기를 클릭하게 되면 주소 뒤에 해쉬로 시작하는 /page3이 추가되고 해당 섹션으로 페이지 내부 이동이 되는 것을 확인할 수 있습니다.

 

 

 

JS
const page1 = `
  <section class="page1">
    <h1>Page 1</h1>
  </section>
`;

const page2 = `
  <section class="page2">
    <h1>Page 2</h1>
  </section>
`;

const page3 = `
  <section class="page3">
    <h1>Page 3</h1>
  </section>
`;

const pageNotFound = `
  <section>
    <h1>404 Page Not Found!</h1>
  </section>
`;

const pages = [
  { path: "#/page1", template: page1 },
  { path: "#/page2", template: page2 },
  { path: "#/page3", template: page3 },
];

const appEl = document.querySelector("#app");

const render = () => {
  //console.log(history)
  const page = pages.find((page) => page.path === location.hash);
  appEl.innerHTML = page ? page.template : pageNotFound;
};

window.addEventListener("popstate", render);
render();

const pagePush = (num) => {
  history.pushState(`전달할 데이터 = ${num}`, null, `#/page${num}`);
  render();
};

const inputEl = document.querySelector("nav input");
inputEl.addEventListener("keydown", (event) => {
  if (event.key === "Enter") {
    pagePush(event.target.value);
  }
});

HTML 마크업을 유지하고 위의 Javascript를 실행하게 되면 스크롤 바가 사라지고 page1번만 view port에 보이게 됩니다.

앞서 작동한 방식과 동일하게 a태그 클릭 시 페이지 내부 이동이 일어나면서 스크롤은 사라졌기 때문에 SPA 방식으로 애플리케이션이 작동하는 것을 확인할 수 있습니다.

 

 

다음으로 input 요소에 2를 입력하고 엔터를 입력하면 /page2에 해당하는 해쉬가 주소에 붙으면서 페이지 내부 이동하는 것을 확인할 수 있습니다. (HTML에 마크업 한 page 1, 2, 3 이외의 값을 입력하게 되면 404 페이지가 나타나게 됩니다. )

 

이는 앞서 언급한 history 객체의 pushState 메서드의 세 번째 인자로 input 요소의 값을 전달하는 이벤트를 추가해주어 히스토리가 추가됨과 동시에 render 함수가 작동하였기 때문입니다.

 

(pagePush 함수에 render 함수를 실행시켜준 이유는 pushState 메서드는 히스토리를 추가를 해주어 주소의 값은 변경이 되자만 페이지 내부 이동은 일어나지 않기 때문에 render함수를 실행시켜 주었습니다. a 태그 클릭의 경우 페이지 이동에 해당하기 때문에 popstate 이벤트가 발생하여 render 함수가 실행됩니다.)

 

render 함수의 경우 location 객체의 hash 속성의 값과 같은 path의 값을 가진 객체를 변수 pages에 할당된 배열에서 찾아 id가 app인 요소에 찾은 객체의 template을 innerHTML로 넣거나, 찾지 못하면 404 요소를 넣어주게 됩니다.

 

 

'JavaScript' 카테고리의 다른 글

원시값과 참조값  (0) 2022.12.23
Symbol, BigInt  (0) 2022.12.23
Location  (0) 2022.12.22
Cookie, Storage  (0) 2022.12.22
Console  (0) 2022.12.22