web-dev-qa-db-ja.com

独自の履歴スタックを単一ページのモバイルWebアプリケーションに実装するにはどうすればよいですか?

BackboneとZeptoで開発されたシングルページモバイルアプリケーションがあります。

ブラウザの戻る/進むボタンで正しく機能します。

ユーザーがページに移動すると、古いコンテンツが左にスライドするので、新しいコンテンツが右からスライドします(およびビューポートから)。ユーザーが「進む」ブラウザボタンを押した場合にも同じことが起こりたいです。これはすべて機能します。

Body要素に追加するクラスがありますnavigate-backこれによりこの動作が反転するため、ユーザーがブラウザの戻るボタンで戻ると、コンテンツが左からスライドして戻る、他のコンテンツが右にスライドするのがわかります。 。基本的には、前進するのとは正反対です。

別の動作を呼び出すことができるように、ユーザーが逆方向にナビゲートしているかどうかを検出する必要があります。独自の履歴スタックを実装しようとしましたが、多くの問題が発生し、前方を後方ナビゲーションとしてマークして、視覚的な手がかりを台無しにすることがあります。それは今ハックの恨みに陥っており、おそらく私がそれを投稿した場合にのみ私を当惑させるでしょう。

ユーザーが単一ページのバックボーンモバイルアプリケーションのコンテキストで前後に移動しているかどうかを検出できるように、独自の履歴スタックを実装するための最良の方法は何ですか?

22
alex

私はbackbone.jsについて知りません1、しかし私はhtml5でこの振る舞いを正確に実装しなければならないモバイルアプリケーションの開発を手伝ったので、私はいくつかの良いアドバイスを与えることができるはずです:

まず、_history.pushState_関数が存在することを知っておくとよいでしょう。ただし、大きな問題は Android 2.3まではサポートされていますが、Android 3 until Android 4.0. 。kiranvjが正しく指摘しているように、これは、履歴機能の欠如に対するポリフィルソリューションを提供する人気のある history.js ライブラリを使用することで解決できます。

さて、実際の問題に取り掛かるにあたり、履歴方向アニメーションを実装する方法は、ページの論理位置を特定するpushState関数(history.pushState(data,title,url))にデータを追加することでした。私のアプリケーションでは、水平バーに限定されていませんでしたが、あなたの場合、新しくロードされたページが現在のページより1つ高い位置になる位置を追跡します。例えば。

_History.pushState({position:History.getState().data.position+1},"Your title","Your URL");
_

次に、_window.onstatechange_または_window.onanchorchange_イベントがトリガーされると、位置が現在のページよりも高いか低いかを観察します(たとえば、 history.jsHistory.getState()上記で使用した関数)、これに応じて、下の画像に示すように、移動する方向を決定します(下が左、上が右)。

Illustration of history events

また、最初のページで_{position:1}_があると既に想定しているのに対し、通常、最初のページには状態情報がないことに注意してください。これを実現する方法は、現在の空の状態をより有益な状態に置き換える_history.replaceState_を使用することです。または、前述のイベントのいずれかで空の状態を確認し、空の場合は左端のイベントであると見なすこともできます(_{position:1}_)。

これがお役に立てば幸いです。他にご不明な点がございましたら、お気軽にお問い合わせください。

この回答は、 history.js を使用していることを前提としていることに注意してください。必要に応じて、わずかに異なるイベント(onpopstateなど)をリッスンし、わずかに異なる構造(historyではなくHistory)を使用する必要があります。独自のソリューションを構築します。

また、独自のキュー配列を使用してこれを構築することも可能であり、これにより、より多くの制御が可能になりますが、ブラウザーの戻るボタンと組み合わせて使用​​することはできません。これはブラウザサイトの大きな問題ですが、 cordova (a.k.a。 phonegap )Webアプリケーションを構築している場合ははるかに簡単です。


1それについて読むだけで、いくつかの履歴処理を行うように見えます それ自体かもしれません統合がより複雑になります上記の手法。

22
David Mulder

単一ページ(複数ビュー)のモバイルでZeptoを操作するときにも、同じ問題が発生しました。

最初はhtml5のstatechangeとonhashchangeを使用していました。それはすべて、1つまたは他のモバイルデバイスでいくつかの問題があります。最後に、ここからZepto履歴プラグインを使用しました https://github.com/browserstate/history.js

それはほとんどの問題をいくらか解決しました。それを試してみてください、それは便利です、それは可能な限りhtml4とhtml5の機能を扱います。

1
kiranvj

trueシングルページアプリで作業している場合は、(history.pushStateなどに依存するのではなく)js変数に履歴URLを保持する配列を設定してみませんか。サポート)?

新しいページに移動するときはいつでも、そのURLを配列にプッシュできます。「戻る」ボタンを押すたびに、必要なURLを必要なだけさかのぼって取得できます。これは、ユーザーが数ステップ戻ってからnewリンクに移動したときに、URLを正しく破棄する限り、完全に機能します。

これをページ履歴に使用するために実装しようとしたことはありませんが、これはページ内の元に戻す-やり直しロジックには完全に機能しました。

更新:

さらに調査した後、上記のアプローチは、JSを通じて利用可能な履歴処理の外部で発生するアクションであるため、ページのリロードには機能しません。前後の遷移を追跡するために引き続き機能しますが、アプリの外部のURLに移動したり、ページを更新したりすると、そのような履歴は失われます。 David Mulderの答えは、ページスコープ外で存続するブラウザレベルの履歴に依存しているため、この制限がないようです。

1
o.v.

これを単一ページのモバイルアプリケーションで使用すると、履歴が表示され、ユーザーが元に戻ります。

function onBackKeyDown() {
    history.go(-1);
    navigator.app.backHistory();
}
0
kiran