SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 社員募集 ...

history.back();問題を解決してみる

history.back()はブラウザの履歴を利用して1つ前のページに戻る機能です。これによりどのページから来た訪問者でも個々のユーザーに合わせたページへ戻ることができます。

この機能、多くのところでは以下のように書かれており、ブラウザからアドレスを入力して開いた場合は機能しません。

<a href="javascript:history.back();">一つ前のページへ戻る</a>

戻るリンクはそのサイトのトップなり1つ上のカテゴリページへ戻ることを意識してリンクをクリックしますので、動かなかったり、検索エンジンへ戻ったりするとユーザーはそのままサイトから離脱している可能性が高いです。

 

そこで対策を考えてみます。直接来た場合はトップページへ返すことを考えます。

まず、history.lengthで考えてみます。これは戻す、進むで使う履歴がいくつあるか取ることができます。ですので、直接開いた場合は1であることが予想されます。しかし、直接来たページから別のページへ移動し、再び戻ってきた場合、lengthは2になってしまいます。数で判定するのはだめそうです。また、訪問履歴の内容(アドレス)を取ることができません。プライバシーとかセキュリティ絡みですのでしょうがないですね。

さて、次にdocument.referrerはどうでしょうか。どこのページから来たかを取得できます。

Javascript

var hBack = (function(){
    var ans;
    var ref = document.referrer;
    re = new RegExp(location.hostname,"i");
    if(ref.match(re)){
        ans = false;
    }else{
        ans = true
    }
    return function(){
        if(!ans){history.back();}
        return ans;
    };
})();

HTML

<a href="index.html" onClick="hBack();" >一つ前のページへ戻る</a>

ただし、これだとリンクを新しいウィンドウで開いた場合にうまく動作しません。リファラーがあるのに履歴を持っていないからです。

そこで見つけたのがこちらのサイト。
要約すると、history.back()が実行できる場合、unloadイベントの類が発生し、出来ない場合は発生しないため、そこにフラグを仕込んで判別する方法のようです。これを踏まえて書き直してみます。ついでにjQuery部なのでjQueryも使います。

Javascript

$(document).ready(function(){
	(function(){
	    var ans; //1つ前のページが同一ドメインかどうか
	    var bs  = false; //unloadイベントが発生したかどうか
	    var ref = document.referrer;
	    $(window).bind("unload beforeunload",function(){
	        bs = true;
	    });
	    re = new RegExp(location.hostname,"i");
	    if(ref.match(re)){
	        ans = true;
	    }else{
	        ans = false;
	    }
	    $('.historyback').bind("click",function(){
                var that = this;
	        if(ans){
	            history.back();
	            setTimeout(function(){
	                if(!bs){
	                    location.href = $(that).attr("href");
	                }
	            },100);
	        }else{
                    location.href = $(this).attr("href");
                }
	        return false;
	    });
	})();
});

HTML

<a href="https://www.softel.co.jp/blogs/jquery/" class="historyback"> 一つ前のページへ戻る </a>
1.リファラーが自ドメインの場合 => history.back();
2.リファラーが自ドメインだが履歴がない場合 => hrefを利用
3.リファラーが自ドメインではない場合(空を含む:直接アドレスから開いた等) => hrefを利用
4.javascriptが動かない場合 => hrefを利用

こんな感じになりました。

DEMO

デモ – history.back();問題を解決してみる。

 

課題

a.history.back()が事前に利用できるかどうかが不明なため、1.の場合に表示先と実際の行き先が異なってしまう。

b.リファラーを教えてくれない環境では常に3になる。

関連するメモ

コメント(1)

T.YAMA 2013年11月19日 19:48

はじめまして。
このスクリプトはとても参考になりました。
しかし、前のページに戻るとリンクがあったその部分にもどってしまいます。
これを戻ったページでページの頭で表示する方法は無いものでしょうか。

分かりにくい質問ですみませんが、よろしくお願いいたします。