모바일 웹앱을 개발하는 과정에서, 메인 parent 페이지을 제외하고 모든 child 페이지에서 최상단에는 항상 ← 뒤로가기 버튼이 존재하게 디자인이 되었다.
보통은 메인 parent 페이지를 통해 child 페이지로 이동하지만, 때로는 외부에서 child 페이지에 바로 접근하는 경우도 생겼다. 이런 경우 뒤로가기 버튼에 history.back() 을 넣으면 아무런 동작을 하지 않게 되는 문제가 드러났다. 어떻게 해야할까?
window.history
제일 먼저 생각난 방법은 history.length를 사용하는 방법이었다. 결론부터 말하면 사용할 수 없는 방법이었다.
history.length 에는 각 링크 이동에 따른 히스토리가 몇 개인지가 기록되어 있는데, 현재 child 페이지에 바로 접근했을 때는 history.length 가 0 또는 1의 값을 갖기 때문에 마치 판별할 수 있을 것 같다. 하지만 child 페이지에서 다른 child 페이지로 한번이라도 링크 이동을 할 경우 history.length 가 증가하게 되고 이렇게 증가된 length는 다시 뒤로가기를 해서 처음 child 페이지로 돌아가도 히스토리 자체는 남아있기 때문에 length 가 줄어들지 않는다.
이런 상태에서는 전체 히스토리 길이만 알 수 있을 뿐 전체 히스토리 상에서 현재 위치(?)를 알 수 없기 때문에 더이상 뒤로가기를 할 수 있는지 없는지 history.length 가 하나라도 더 증가되면 알 길이 없다.
따라서 history.length는 처음 진입한 child 페이지에서 더이상 뒤로가기 히스토리가 없다는 것을 판별할 수 있는 방법이 아니다.
document.referrer
방법이 없을까 계속 찾던 중 document.referrer 가 해답이 될 수 있음을 발견했다.
document.referrer 는 링크를 통해 이동했을 때 어떤 페이지의 링크를 통해 왔는지 레퍼러가 기록되는 공간이다. 따라서 바로 타이핑해서 직접 특정 페이지로 들어갈 경우 이 referrer 가 존재하지 않게 되므로 그게 첫 페이지임을 알 수 있다.
아래의 코드를 살펴보자.
이렇게 할 경우, 효과적으로 뒤로 가기할 곳이 없을 때 메인 페이지로 이동할 수 있게 된다.
깔끔하게 한 줄짜리 코드로 변환하면 아래와 같이 바꿀 수 있다.
그런데 만약 타사 페이지에서 링크로 child 페이지로 이동했을 경우에는 referrer 가 존재하기 때문에 뒤로가기를 하면 링크를 타고 타사 페이지로 이동하게 된다. 그런데 웹앱이라는 개념을 생각할 때 이것보다는 뒤로가기를 했을 때 메인 페이지로 돌아가고 싶을 수 있다.
이런 경우를 위해 조금더 신경을 쓰면 아래와 같이 바꿔줄 수 있다.
한줄 짜리로 바꿔주면 아래와 같이 압축할 수 있다.
마치며
단순히 history.back() 으로 아무런 예외처리 없이 처리한 것을 보면서 개선할 수 없을지를 고민하다가 document.referrer 를 활용한 방법을 찾았다.
물론 단점이 없지는 않다. AJAX를 활용한 페이지 이동이나, 해시값의 변화는 referrer 를 통해서 확인할 수 없다. 이런 경우에는 HTML5 의 History API 를 활용해서 처리해야할 지도 모르겠다.
좀더 정교하게 이 부분을 다듬어가면 좀더 사용자 경험을 개선할 수 있지 않을까 생각해본다.
보통은 메인 parent 페이지를 통해 child 페이지로 이동하지만, 때로는 외부에서 child 페이지에 바로 접근하는 경우도 생겼다. 이런 경우 뒤로가기 버튼에 history.back() 을 넣으면 아무런 동작을 하지 않게 되는 문제가 드러났다. 어떻게 해야할까?
window.history
제일 먼저 생각난 방법은 history.length를 사용하는 방법이었다. 결론부터 말하면 사용할 수 없는 방법이었다.
history.length 에는 각 링크 이동에 따른 히스토리가 몇 개인지가 기록되어 있는데, 현재 child 페이지에 바로 접근했을 때는 history.length 가 0 또는 1의 값을 갖기 때문에 마치 판별할 수 있을 것 같다. 하지만 child 페이지에서 다른 child 페이지로 한번이라도 링크 이동을 할 경우 history.length 가 증가하게 되고 이렇게 증가된 length는 다시 뒤로가기를 해서 처음 child 페이지로 돌아가도 히스토리 자체는 남아있기 때문에 length 가 줄어들지 않는다.
이런 상태에서는 전체 히스토리 길이만 알 수 있을 뿐 전체 히스토리 상에서 현재 위치(?)를 알 수 없기 때문에 더이상 뒤로가기를 할 수 있는지 없는지 history.length 가 하나라도 더 증가되면 알 길이 없다.
따라서 history.length는 처음 진입한 child 페이지에서 더이상 뒤로가기 히스토리가 없다는 것을 판별할 수 있는 방법이 아니다.
document.referrer
방법이 없을까 계속 찾던 중 document.referrer 가 해답이 될 수 있음을 발견했다.
document.referrer 는 링크를 통해 이동했을 때 어떤 페이지의 링크를 통해 왔는지 레퍼러가 기록되는 공간이다. 따라서 바로 타이핑해서 직접 특정 페이지로 들어갈 경우 이 referrer 가 존재하지 않게 되므로 그게 첫 페이지임을 알 수 있다.
아래의 코드를 살펴보자.
//뒤로갈 히스토리가 있으면, if ( document.referrer ) { // 뒤로가기 history.back(); } // 히스토리가 없으면, else { // 메인 페이지로 location.href = "http://m.naver.com"; }
이렇게 할 경우, 효과적으로 뒤로 가기할 곳이 없을 때 메인 페이지로 이동할 수 있게 된다.
깔끔하게 한 줄짜리 코드로 변환하면 아래와 같이 바꿀 수 있다.
document.referrer ? history.back() : location.href="http://m.naver.com";
그런데 만약 타사 페이지에서 링크로 child 페이지로 이동했을 경우에는 referrer 가 존재하기 때문에 뒤로가기를 하면 링크를 타고 타사 페이지로 이동하게 된다. 그런데 웹앱이라는 개념을 생각할 때 이것보다는 뒤로가기를 했을 때 메인 페이지로 돌아가고 싶을 수 있다.
이런 경우를 위해 조금더 신경을 쓰면 아래와 같이 바꿔줄 수 있다.
//뒤로갈 히스토리가 있으면, if ( document.referrer && document.referrer.indexOf("naver.com") != -1 ) { // 뒤로가기 history.back(); } // 히스토리가 없으면, else { // 메인 페이지로 location.href = "http://m.naver.com"; }
한줄 짜리로 바꿔주면 아래와 같이 압축할 수 있다.
document.referrer&&-1!=document.referrer.indexOf("naver.com")?history.back():location.href="http://m.naver.com";
마치며
단순히 history.back() 으로 아무런 예외처리 없이 처리한 것을 보면서 개선할 수 없을지를 고민하다가 document.referrer 를 활용한 방법을 찾았다.
물론 단점이 없지는 않다. AJAX를 활용한 페이지 이동이나, 해시값의 변화는 referrer 를 통해서 확인할 수 없다. 이런 경우에는 HTML5 의 History API 를 활용해서 처리해야할 지도 모르겠다.
좀더 정교하게 이 부분을 다듬어가면 좀더 사용자 경험을 개선할 수 있지 않을까 생각해본다.