LoginSignup
5
5

More than 5 years have passed since last update.

PushStateとPopSatateを使った暗黒魔術

Posted at

顧客情報とか秘匿したままページ遷移したい場合、Ajax とPushState+PopState のPjax が便利ですよね(IE? ヤツは死んだよ。)

で、まあ今作ってるサイトもそれでいけるかなーと思ったんですがなかなかくせ者でした。
上記ライブラリ自体が後付けって理由もなきにしもあらずなんですが、PHPフレームワークを使用しながらモーダルからAjax でページ更新する場合,

http://[host_name]/#

#はあってもなくてもいいんですがこの形なら正常にHTMLの上書きができるのですが

http://[host_name]/index/index/index

みたいな形だと何故かAjax処理の部分で失敗してうまく動いてくれません。
なので
PushStateのURI書き換え機能を利用して
URIを書き換えて

http://[host_name]/#

としてページのリロードをしてます。

逆にPopStateでブラウザバックする場合、

http://[host_name]/index/index/index

の形式ならうまくページ遷移してくれるんですが

http://[host_name]/#

の形式になっていると今度はこちらが上手く遷移してくれない。
はい、逆の発想ですね。

PushStateのURI書き換え機能を利用して
URIを

http://[host_name]/index/index/index

に変換してからページをリロードです。
ソースにするとつまりこういうこと

モーダルから次画面遷移

if (window.history && window.history.pushState){
    state = document.title;
    history.pushState(state, "", url);
    location.reload();
}
$("#target-element").html(data);    //target-elementには実際に書き換えたい要素(IDなど) を入力

ブラウザバックでインデックスに戻る

function loadContents(url) {
    $.get(url, { push_state: 'true' }).then(function(content) {
        if(document.URL.match(/..#/)) {
            var url = 'index/index';
            history.pushState("", "", url);
            location.reload();
        } else {
            $('html').html(content);
            location.reload();
        }
    });
}
// handlling popState event
read = false;
previous_location = location.href;
$(window).on('popstate', function(e){
    // prevent scanning below code twice or more
    if (read == false && previous_location != location.href) {
        if(location.href != location.pathname) {
            loadContents(location.pathname);
        }
            read = true;
    }

});

こんなクソコード書くのに半日かかりましたとさ。
めでたしめでたし。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5