3

私の 1 ページの Web アプリでは、一部のページに、ユーザーがブラウザー履歴の特定のポイントに戻るための戻るボタンが必要です。必ずしも前のページではありません。

ブラウザの戻るボタンについて話しているのではないことに注意してください。これは通常どおり機能するはずです。

使用事例

例として、gmail Web アプリについて考えてみましょう。場合によっては検索フィルターやその他のパラメーターを含むフォルダー ビューと、1 つのメッセージを表示するメッセージ ビューがあります。メッセージ ビューには、前のページに移動しない戻るボタンがあります。いくつかのメッセージをクリックして読み回した場合でも、戻るボタンをクリックすると、元のフォルダ ビューに戻ります。メッセージの。

gmail の場合、これは URL の最後に以前の状態をエンコードするだけで実現されます。たとえば、検索してこのメ​​ッセージにたどり着いた場合、次のようになります。

#search/stuff/<MESSAGE_ID>

このことから、アプリは、戻るボタンが次のページを指す必要があることを認識しています。

#search/stuff

しかし、私のアプリケーションでは、状態が多すぎてすべてを URL にエンコードできません。2 つのビュー (フォルダー + メッセージ) ではなく、3 つのビューがあります。それらを A、B、および詳細と呼びましょう。たとえば、B から A に、または詳細から B に戻ります。A、B、および詳細のすべてのパラメータを詳細ページの URL にエンコードすると、URL が非常に扱いにくくなります。

実装

これは、html5 history API を使用して簡単に実現できると思いました。ただし、私が知る限り、履歴 API は履歴内の URL の読み取りをサポートしていません。やみくもに戻るか進むことしかできません。

関連する質問で説明されているように、history.js は過去の状態へのアクセスを提供します。

History API: Javascript Pushstate、以前の URL を取得

しかし、私は history.js ではうまく動作しない angularjs を使用しています。これは、history.js を経由するのではなく、履歴 API と直接やり取りするため、angular $location サービスによって引き起こされた遷移の状態が履歴に表示されないためです。 .js の History オブジェクト。

次のいずれかを行う必要があるようです。

  • history.js を angular でうまく機能させる
  • 自分のコードで history.js の機能のサブセットを再実装する

document.referrer を使用して履歴の前の値を確認することも検討しましたが、1 ページ アプリ内を移動するときに設定されないため、これは機能しません。

4

2 に答える 2

1

私自身の質問に答えて、@MaxArt のコメントで提案されたより単純なソリューションを選択しました。

  • ページのランダム ID を生成する
    • 私はangularjsを使用しているので、これを $on('$routeChangeSuccess') または $on('$routeUpdate') します
    • angularjsがなければ、これをonpopstateで行うと思います
  • このランダム ID から、必要なすべての URL 情報 (私の場合は検索とパス) へのマッピングを sessionStorage に保存します。
  • アプリの概念階層を進む発信リンクに現在のページの ID = からの検索パラメーターを含めます
  • カスタムの [戻る] ボタンがクリックされたら、from seach パラメータを使用して sessionStorage で元の状態を検索します
    • 見つかった場合は、その URL に戻ります
    • 見つからない場合 (ユーザーがこのページに直接移動した場合)、アプリの階層内の前のビューのデフォルト URL に戻ります

過去の URL の履歴を構築するというより一般的なアプローチよりも、このアプローチを採用する理由は次のとおりです。

  • 前述のとおり、pushState API は過去の URL へのアクセスを提供しません
  • その情報を提供する History.js を angularjs に統合することは簡単ではないようです
    • angularjs は履歴 API を内部で使用します。代わりに History を使用するように変更する必要があります。
  • URL 履歴を sessionStorage に記録するためのカスタム コードの実装も簡単ではありません。主な問題は、ブラウザーの履歴との統合が欠けているため、訪問したページが新しいものなのか、それともブラウザーの履歴の 1 つまたは複数のステップをさかのぼってアクセスしたものなのかを知る一般的な方法がないように思われることです。誰かが解決策を提案できる場合は、これについて修正していただければ幸いです (1)
  • History.js またはすべての history.pushState を追加のコードでラップする同等のソリューションを使用するには、ページ上のほぼすべてのリンクを History.pushState でラップする必要があります。そうしないと、URL の変更が履歴に表示されません。

(1) popstate イベントが HTML5 プッシュステートの back または forward アクションから来ているかどうかを取得するにはどうすればよいですか?

于 2013-06-12T18:30:58.197 に答える
0

angular.js を使用したことはありませんが、動作が保証されているものが必要な場合は、window.history.pushState を探していると思われます。この赤ちゃんができることの詳細については、 http://spoiledmilk.com/blog/html5-ching-the-browser-url-without-refreshing-page/を読んでください。

于 2013-06-12T02:56:06.297 に答える