본문 바로가기

[IT/Programming]/HTML related

Change browser URL (window.location) without reloading or redirecting a page

반응형
# Change browser URL or URI (window.location, Unique Resource Identifier) without reloading or redirecting a page 페이지를 일부만 바꾸고 싶을때, 혹은 JavaScript 변수들/데이터들을 유지하고 싶을때, 주로 AJAX request 를 이용한다. 그런데 사용자에게 일부가 바뀐 이 페이지의 주소는 이것이다라고 알려주고 다른 사람들과 공유하기 편하게 하려면, 바뀐 페이지에 바로 접속할 수 있는 주소로 URL (window.location) 이 바뀌어주는 것이 좋아보인다. 물론 이 주소로 접속을 하면 서버에서는 그 바뀐 페이지를 다시 보여주도록 디자인되어야 할테고. 인스타그램, 페이스북, GitHub 등의 사이트들에서 몇가지 (특히 navigation menu) 를 이렇게 구현해 놓은 것 같다. 전체 주소뒤에 hash(#) 를 붙여서 하는게 아니라, URL 의 domain part 를 제외한 path 부분을 page reload 없이 바꾸는 형태로 동작한다. 물론 내부적으로는 AJAX 로 데이터를 주고 받을듯 하지만 페이지가 완전히 reload/redirect 되는 것은 아니고 일부분만 바뀐다. 그리고 이렇게 바뀌어진 URL 로 새 창에서 접속해도 비슷한 화면이 띄워진다. (구현 방법에 따라 완전히 똑같은 화면은 안뜰수도 있음.) ## TOC ## Browser Objects - window.location 기본적으로 JavaScript Browser Objects 에 window.location 이란게 있음 . ### All properties of window.location






### URL 의 기본구조

전체 URL 은 위에서 보이듯 href 로 뽑아낼 수 있음. 이 URL 은

```[.linenums.lang-html]
// The entire URL
[href]=[protocol]//[hostname]:[port][/pathname][?search][#hash]
	=[protocol]//[host][/pathname][?search][#hash]
	=[origin][/pathname][?search][#hash]

// Host
[host]=[hostname]:[port]

// Origin
[origin]=[protocol]//[hostname]:[port]
	=[protocol]//[host]
```/

형태로 구성되어 있음.



### Change URL

이 window.location 을 이용해서 URL 을 다음과 같은 명령어들로 바꿀 수 있음. 그런데 이걸 이용하면 바뀐 URL 에 해당하는 페이지를 아예 새로 load 함 (hash 만 제외).

```[.scrollable.lang-js]
// 새로고침
window.location.reload();

// 아예 새로운 URL 로 이동.
window.location="http://www.daum.net";
window.location.href="http://www.daum.net";
window.location.assign("http://www.daum.net");
window.location.replace("http://www.daum.net");
	// replace 는 뒤로가기 활성화 안됨.

// path 부분만 바꿔서 이동.
window.location="/new/path";
window.location.href="/new/path";
window.location.pathname="new/path";
window.location.pathname="/new/path";

// path 의 마지막 부분만 바꿔서 이동.
window.location.href="the-last-path/is/changed";
	// window.location.pathname= 로는 처음에 "/" 가 없어도 전체 path 가 바뀜.

// host 부분만 바꿀수도 있는듯? 쓸일은 거의 없겠지만...
window.location.host="tistory.com";
window.location.hostname="tistory.com";

// query 부분 (?이후-부분) 바꾸기.
window.location="?a=b&c=d";
	// 이 경우 hash 는 지워짐.
window.location.search="a=b&c=d";
	// The querystring part is the part of the URL after the question mark (?). This is often used for parameter passing.

// hash 부분 (#이후-부분) 바꾸기. 이건 page reload 없음.
window.location="#some-hash";
window.location.hash="some-hash";
	// When used to set the anchor part, do not include the hash sign (#).
```/



## Change browser URL without redirecting a page

window.history 를 이용하면, page reload 없이도 URL path 부분을 바꿀 수 있음. 참고 : . (그런데 history 안의 URL list 는 못 뽑아내는듯? 보안문제 때문인가?)





### Traveling through history : window.history - .back(), .forward(), .go(Number n)

window.history 는 이름에서도 알 수 있듯이 기본적으로 "뒤로 가기", "앞으로 가기" 등에 쓰였던 JavaScript Object 임. 다음과 같은 javascript 명령어들로 "뒤로 가기", "앞으로 가기" 등이 실행 가능함.

```[.linenums.lang-js]
// 뒤로 가기
window.history.back();
window.history.go(-1);

// 앞으로 가기
window.history.forward();
window.history.go(1);

// 뒤로 두번 가기
window.history.go(-2);

// 앞으로 두번 가기
window.history.go(2);
```/



### window.history .pushState()

아래와 같은 명령어를 console 창에 치면 page reload 없이 URL 의 path 부분이 바뀌는 것을 알 수 있음. 또한 뒤로가기도 활성화 됨. (크롬에서만 그런건지 모르겠는데, 스크롤 위치가 바뀔 경우 스크롤 위치도 기억했다가 되돌리는듯?)

```[.linenums.lang-js]
window.history.pushState({JSON:"data"}, "title" [, "/new-path?search#hash"]);
	// pushState() takes three parameters: a state object, a title (which is currently ignored), and (optionally) a URL.
	// 첫번째 parameter {JSON:"data"} 는 window.history.state 에 저장되어서 나중에 뽑아낼 수 있음.
	// 두번째 parameter 는 아직 쓰이는데가 없는듯? 왜 만든겨?
	// 세번째 parameter 가 URL path 를 바꿈. "search, hash" 값을 포함하는 full path 가 들어감.

// State 만 update
window.history.pushState({JSON:"new state"}, null);

// 전체 path 바꾸기
window.history.pushState(null, null, "/path/will/be/changed/null");
window.history.pushState({some:"data1"}, "state1", "/path/will/be/changed/state1?a=b&c=d#state1");
window.history.pushState({some:"data2"}, "state2", "/path/will/be/changed/state2");
window.history.pushState({some:"data3"}, "state3", "/path/will/be/changed/state3?a=c&b=d#state3");
window.history.pushState({some:"data4"}, "state4", "/path/will/be/changed/state4");
window.history.pushState({some:"data5"}, "state5", "/path/will/be/changed/state5");
window.history.pushState({some:"data6"}, "state6", "/path/will/be/changed/state6");
window.history.pushState({some:"data7"}, "state7", "/path/will/be/changed/state7?a=b&c=d#state7");

// 마지막 path 만 바꾸기
window.history.pushState(null, null, "the-last-path/will/be/changed");
```/



### window.history .replaceState()

다음과 같은 명령어로는 "뒤로 가기"를 활성화 안시키고 URL path 를 바꿀수 있음.

```[.linenums.lang-js]
window.history.replaceState({JSON:"data"}, "title", "/new-path");

// 전체 path 바꾸기
window.history.replaceState({}, "", "/path/will/be/changed");

// 마지막 path 만 바꾸기
window.history.replaceState({}, "", "the-last-path/will/be/changed");
```/



## window .onpopstate

Whenever the user navigates to the new state, a popstate event is fired, and the state property of the event contains a copy of the history entry's state object.

아래와 같이 function 을 window.onpopstate 에 asign 해 놓으면, "앞으로 가기"/"뒤로 가기" 등으로 state 가 바뀔때마다 해당 function 이 불려짐. 따라서 페이지가 처음 불려질때나 reload 될때는 call 되지 않음. window.history.pushState() 가 실행될때도 불려지지 않음. (그런데 window.onpopstate 이용해서 구현한 사이트들은 거의 없는듯?)

```[.linenums.lang-js]
// 기본적으로 window.onpopstate 는 null 임.
window.onpopstate=function(e) {
	console.log(e.state);
};
```/

아래는 개인적으로 넣어놓은 onpopstate 가 불려질때 event.state, event 의 all properties 출력 결과. State 들 몇개를 넣어놨으니 뒤로가기를 눌러보시길. (setTimout 은 state 가 바뀐 뒤에도 동작을 함 =ㅇ=;;; 스크롤이 제멋대로길래 $(window).scrollTop() 를 이용했는데, 브라우저 기본동작이 내껄 덮어씌우길래 setTimeout 걸어놨음. 아마도 onpopstate function 이 불려지고 난 후, 이전 스크롤 위치를 찾아가는 scroll function 이 불려지는듯?)

```[#onpopstate-result.linenums.scrollable.lang-js]
```/



## RRA

  1. MDN - Manipulating the browser history
  2. w3schools - Browser Objects Reference - The Location Object
  3. StackOverflow - Modify the URL without reloading the page, 2009-05-05, asked by Jarvis, answered by David Murdoch
  4. spoiledmilk.com/blog - HTML5: Changing the browser-URL without refreshing page, 2010-07-20
  5. Tinywall.info - Change browser url without page reloading with ajax request using JavaScript, HTML5 history API, jQuery, PHP like Facebook, Github navigation menu, 2012-02-22, by Arun David
    // 코드들이 예쁘게 정리되어 있지 않은게 아쉽당.
반응형