web-dev-qa-db-ja.com

JavaScriptでハッシュ/アンカーの変更の履歴を保持する

私は現在、アドレスバーのハッシュ部分への変更の履歴を追跡するJavaScriptライブラリを実装しています。ハッシュ部分に状態を保持してから、戻るボタンを使用して前の状態に戻ることができるという考え方です。

最近のほとんどのブラウザーでは、これは自動であり、変更についてlocation.hashプロパティをポーリングするだけで済みます(IE8では、それを行う必要はありません。関数をonhashchangeイベントにアタッチするだけです)。

私が疑問に思っているのは、履歴を追跡するためにどのような異なる方法がありますか? Internet Explorer 6/7/8、Firefox、Chromeで動作することがテストされている機能を実装しましたが、他のブラウザーはどうですか?これが私が現在履歴を保持する方法です:

編集:さまざまなブラウザのウォークスルーについては、代わりに以下の私の回答を参照してください。

28
Blixt

まず第一に、答えてくれた皆さんに感謝します! =)

私は今、さらに多くの研究を行い、自分の実装に満足していると信じています。これが私の研究結果です。

まず第一に、 私の完成したHashライブラリ 。これは、依存関係のないスタンドアロンライブラリです。 Hash.init(callback, iframe)Hash.go(newHash)の2つの関数があります。コールバック関数は、最初の引数として新しいハッシュを使用してハッシュが変更されるたびに呼び出され、2番目の引数として、初期状態(true)またはハッシュの実際の変更(false)によってコールバックが呼び出されるかどうかを示すフラグが呼び出されます。

Hash.js (MITライセンス)

また、使いやすくするためのjQueryプラグインも作成しました。グローバルhashchangeイベントも追加します。使用方法については、ソースコードの例を参照してください。

jquery.hash.js (MITライセンス)

それらが使用されていることを確認するには、JavaScriptの「レルム」ページにアクセスしてください。

BlixtのJavaScriptレルム

Internet Explorer 8

スムーズなクルージング! onhashchangeイベントをwindowオブジェクトに(attachEventを使用して)1つ叩き、イベントハンドラーでlocation.hash値を取得します。

ユーザーがハッシュ付きのリンクをクリックするかどうか、またはプログラムでハッシュを設定するかどうかは関係ありません。歴史は完璧に保たれています。

Chrome、Firefox、Safari 3以降、Opera 8+

スムーズなクルージング! setIntervalと関数を使用して、location.hashプロパティへの変更をポーリングするだけです。

歴史は完璧に機能します。 Operaの場合、history.navigationMode'compatible'に設定しました。正直なところ、何をするのかわかりませんが、YUIコードのコメントからの推薦でやりました。

:Opera追加のテストが必要ですが、機能しましたこれまでのところ私にとっては問題ありません。

サプライズ癖ボーナス! (できますか?!)Firefox(3.5以降でのみ確認済み)がlocation.hashプロパティをデコードすることが判明したため、これによりhashchangeイベントが2回(最初にエンコードされたバージョンの場合、エンコードされていないバージョンの場合。)代わりにlocation.hrefプロパティを使用してこれを考慮した新しいバージョンのHash.jsライブラリがあります(変更はAaron Ogleによって提供されます)

Internet Explorer 6、7

今では厄介になります。古いInternetExplorerバージョンのナビゲーション履歴は、ハッシュの変更を無視します。これを回避するために一般的に受け入れられている解決策は、iframeを作成し、そのコンテンツを新しいハッシュに設定することです。これにより、ナビゲーション履歴に新しいエントリが作成されます。ユーザーが戻ると、これによりiframeのコンテンツが以前のコンテンツに変更されます。コンテンツの変更を検出することで、コンテンツを取得してアクティブハッシュとして設定できます。

現在のアドレスを手動で変更するには、location.hashプロパティへの変更を確認する必要があります。ただし、以下で説明する癖に注意してください。

このソリューションは世の中で最高のソリューションのようですが、Internet Explorer 6ではまだ完璧ではありません。これは、戻る/進むボタンについて少し風変わりです。ただし、Internet Explorer7は正常に動作します。

サプライズクォークボーナス#1!Internet Explorer 6では、ハッシュに疑問符がある場合は常に、これ抽出されてlocation.searchproperty!location.hashプロパティから削除されます。ただし、実際のクエリ文字列がある場合は、location.search代わりにその文字列が含まれ、location.hrefプロパティを解析することによってのみ真のハッシュ全体を取得できます。

サプライズクォークボーナス#2!location.searchプロパティが設定されている場合、後続#文字はlocation.href(andlocation.hash)プロパティから削除されます。 Internet Explorer 6では、これは、パスまたはハッシュに疑問符がある場合は常に、この癖が発生することを意味します。 Internet Explorer 7では、この癖はパスに疑問符がある場合にのみ発生します。 Internet Explorerの一貫性が好きではありませんか?

サプライズクォークボーナス#3!ページ上の別の要素がaの値と同じIDを持っている場合ハッシュ、そのハッシュは完全に歴史を台無しにします。したがって、経験則では、ページ上の他の要素と同じIDのハッシュは避けてください。ハッシュが動的に生成され、IDと衝突する可能性がある場合は、プレフィックス/サフィックスの使用を検討してください。

他のブラウザ

並外れたユーザーベースを持っていない限り、より多くのブラウザをサポートする必要はありません。上記にリストされていないブラウザは、1%未満の使用カテゴリにあります。

32
Blixt

あなたがこれに注いだ努力に基づいて、私はあなたが見たことがあると思います YUI Browser History Manager 、しかし念のために...

彼らは彼らの実装について素晴らしい記事を書いています、そして私は彼らのソースコードがとても読みやすいと思います。

これがOperaについての説明です

* location.hash is a bit buggy on Opera. I have seen instances where
* navigating the history using the back/forward buttons, and hence
* changing the URL, would not change location.hash. That's ok, the
* implementation of an equivalent is trivial ... more below

ソースを検索すると、Safari1.xと2.0の宿泊施設もいくつか見つかりました。あなたはそれに興味があるようです。

お役に立てば幸いです。

3
Keith Bentrup

私はあなたのニーズを完全に理解しているかどうかはわかりませんが、Really Simple Historyライブラリ( http://code.google.com/p/reallysimplehistory/ )を使用して同様のことを実装しました。あなたはここでそれを見ることができます: http://whiteoak.sourceforge.net/

1
Itay Maman

何を言おうとしているのか、どこにも言及されていないので、共有して、それがどれほど一般的な知識であるかを見てみたいと思いました。

IE(IE7でのみ検証済み)では、ハッシュと等しいIDを持つページ要素が画面にある場合、ハッシュの履歴は正しく機能します。たとえば、次のテーブルについて考えてみます。 Wikiページの目次(TOC)。目次の各リンクは、ページのどこかにあるidまたはアンカー名要素のハッシュにリンクしています。

<div id="TOC">
<a id="SampleHeaderLink" href="#SampleHeader">Sample Header</a>
</div>

<h2 id="SampleHeader">Sample Header</a>

したがって、SampleHeaderLinkをクリックすると、IEブラウザーのデフォルト設定では、SampleHeaderに移動し、履歴に状態を登録します。戻るボタンと進むボタンを使用すると、期待どおりに機能します。

ただし、SampleHeader divがページに存在しない場合、ブラウザーは変更されたURLを登録するだけで、新しい状態を作成しません。

繰り返しますが、これはIE7でのみ検証されています。そして、私はこの情報がどれほど一般的であるかを知りませんが、私が自分のアプリケーションでこの問題を修正するために閲覧していたとき、関連するものは何も見つかりませんでした。

0
Beez