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

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

新規登録して質問してみよう
ただいま回答率
85.48%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

2回答

8500閲覧

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

massuguda

総合スコア23

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2019/05/12 05:45

編集2019/05/12 06:08

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

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

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

###【Pjax処理】
まず次のような流れでやっております。

jQuery

1// Pjaxの関数 2function pjax(url) { 3 $.ajax({ 4 type: 'GET', 5 url: url, 6 dataType: 'html' 7 }) 8 .done(function(data) { 9 // コンテンツを入れ替える 10 var contentItems = $(data).find('#main'); 11 $('#main').html(''); 12 $('#main').html(contentItems); 13 // 履歴を追加し、コンテンツを保存しておく 14 history.pushState({name : contentItems}, '', url); 15 }) 16 .fail(function () { 17 alert('error'); 18 }); 19} 20 21// Pjaxの実行(リンクのクリックでのPjax) 22$(document).on('click','a',function(e){ 23 e.preventDefault(); 24 var url = $(this).attr('href'); 25 pjax(url); 26}); 27

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

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

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

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

jQuery

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

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

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

jQuery

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

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

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

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

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

まず、普通に何でもいいのでネットをブラウザで開き、リンクを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](https://developer.mozilla.org/ja/docs/Web/Guide/DOM/Manipulating_the_browser_history#replaceState(%29_%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89)

投稿2019/05/13 07:21

Lhankor_Mhy

総合スコア36104

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

massuguda

2019/05/29 14:39

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

0

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

投稿2019/05/13 02:00

yambejp

総合スコア114829

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

massuguda

2019/05/29 14:40

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問