質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.07%

ある条件下の「popstate」では、ブラウザの「戻る・進む」が効かなくなる現象について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 4,528

score 20

Pjaxにあたり、ブラウザの「戻る・進む」に対応させています。

Pjaxの処理はできたのですが、popstateの処理につきまして疑問が生じたために質問させて頂きました。

お詳しい方がいらっしゃいましたら宜しくお願い致します。

【Pjax処理】

まず次のような流れでやっております。

// Pjaxの関数
function pjax(url) {
    $.ajax({
        type: 'GET',
        url: url,
        dataType: 'html'
    })
    .done(function(data) {
        // コンテンツを入れ替える       
        var contentItems = $(data).find('#main');
        $('#main').html('');
        $('#main').html(contentItems);    
        // 履歴を追加し、コンテンツを保存しておく
        history.pushState({name : contentItems}, '', url);
    })
    .fail(function () {
        alert('error');            
    });
}        

// Pjaxの実行(リンクのクリックでのPjax)
$(document).on('click','a',function(e){
    e.preventDefault();
    var url = $(this).attr('href');
    pjax(url);    
});


上記特に問題ないかと思いますが、お聞きしたいのは次の2つの処理です。

【処理A】では「戻る・進む」が効く一方で、

【処理B】では一回しか戻れない上に、進むがグレーアウトしてクリックできなくなってしまうです。

【処理A】

まずこちらが問題のない方で、「戻る・進む」が効きます。
【Pjax処理】で取得しておいた{name : contentItems}から、state.nameとしてコンテンツを表示するというアプローチです。

// Pjaxの実行(戻る・進むでのPjax)
window.addEventListener('popstate', function(e) {
    $('#main').html(e.state.name);
});

【処理B】

続きましてこちらですが、【処理A】と違って【Pjax処理】で取得しておいた{name : contentItems}を使うのではなく、新たにpjax(url);を実行するというアプローチになります。

この場合、一回戻るとそれ以上戻れず、進むこともできなくなるのです。

// Pjaxの実行(戻る・進むでのPjax)
$(window).on('popstate', function(e){
    var url = location.pathname;
    pjax(url);   
});

質問事項のまとめ

お聞きしたいことをまとめますと次の2つになります。

➀上の【処理A】と【処理B】を比べたうえで、後者の問題点はなにか?

➁もし【処理B】のアプローチ(新たにpjax(url);を実行するというアプローチ)を採用する場合、直すべき点はどこか?

以上です。
どうぞ宜しくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

進むがグレーアウトしてクリックできなくなってしまう

まず、普通に何でもいいのでネットをブラウザで開き、リンクを3つたどってみて下さい。
コンソールでhistory.lengthを調べると、4になってるかと思います。

次に、「戻る」を押してください。「進む」が有効になると思います。さらにどんどん戻って最初のページに言ってください。「戻る」が無効になるかと思います。
コンソールでhistory.lengthを調べると、4になってるかと思います。

ここで、今までとは別のリンクを踏んでみてください。
そうすると、「戻る」が有効になって、「進む」が無効になるかと思います。
コンソールでhistory.lengthを調べると、2になってるかと思います。

つまり、履歴の途中で新たな履歴エントリを作ってしまうと、そこより先の履歴エントリが破棄されるという仕様です。
A→B→C→D
というページ移動をして、Aページまで戻りEページに行くと
A→E→B→C→D
にはならず、
A→E
になるということです。
pushStateでも同じことで、個人的には、これは自然な動作のように思えます。

一回しか戻れない

popstateイベント発生時に履歴エントリを追加する動作ですから、
A→B→C
ここで「戻る」を押すと、Bページをpjaxで取得し履歴エントリとして追加しますから、
A→B→B
という履歴になります。
そして、ここで「戻る」を押すと、Bページをpjaxで取得し履歴エントリとして追加しますから、
A→B→B
という履歴になります。
そして、……という具合に、延々とBページに戻り続けます。

直すべき点はどこか

popstateイベント発生時に履歴エントリを追加するのをやめてはいかがでしょう。
内容の変更をしたいのであれば、↓こちらを使うのが正しいのではないかと思います。

replaceState() は新しく履歴エントリを作成する代わりに現在の履歴エントリを修正します。
ブラウザの履歴を操作する - ウェブデベロッパーガイド | MDN

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/29 23:39

    するどい分析に感謝致します。参考リンクを元に実装できました。どうもありがとうございました。

    キャンセル

0

pjaxの仕様をいまいち理解していないので当てずっぽうになりますが
pageshowあたりでどうでしょうか?
もしくはMutationObserverあたりでchildListを監視するとか

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/29 23:40

    いずれも次善の策として使えそうですね。今後の参考にさせていただきます。ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.07%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る