web-dev-qa-db-ja.com

ロケーションハッシュを置き換えて、最後の履歴エントリのみを保持するにはどうすればよいですか?

jQuery BBQプラグイン を使用して、ページ内のユーザーの進行状況を追跡しています。ただし、ハッシュの変更ごとに1つではなく、ユーザーの履歴に1つの追加エントリのみを作成したいと思います。

_jQuery.bbq.pushState_および _merge_mode_ メソッドを試しましたが、成功しませんでした。新しい履歴エントリがまだ追加されています。

_jQuery.bbq.pushState({ sort: encodeURIComponent(sort) });
_

location.replace()も試しましたが、Safari5.1.2では機能しません。

_location.replace('#' + encodeURIComponent(sort))
_

履歴にあまり多くのエントリを追加せずにハッシュを変更するためのクロスブラウザソリューションは何ですか?

16
Hoppe

最初に、関数replaceHashの定義を示します。これは、新しい場所のハッシュという1つの引数のみを受け入れます。ロジックの詳細な説明は、回答の下部にあります。

コード:

_// Should be executed BEFORE any hash change has occurred.
(function(namespace) { // Closure to protect local variable "var hash"
    if ('replaceState' in history) { // Yay, supported!
        namespace.replaceHash = function(newhash) {
            if ((''+newhash).charAt(0) !== '#') newhash = '#' + newhash;
            history.replaceState('', '', newhash);
        }
    } else {
        var hash = location.hash;
        namespace.replaceHash = function(newhash) {
            if (location.hash !== hash) history.back();
            location.hash = newhash;
        };
    }
})(window);
// This function can be namespaced. In this example, we define it on window:
window.replaceHash('Newhashvariable');
_

機能ロジック

  • _history.replaceState_ がサポートされている場合、関数は常に現在のハッシュを置き換え、副作用はありません。
  • それ以外の場合は、最初の_location.hash_プロパティへの参照(hash)が作成され、次の関数が定義されます。

    1. _location.hash != hash_の場合、履歴の状態が少なくとも最初のページビューを超えていることが確実にわかります。ページをアンロードせずに、安全に履歴に戻ることができます。 history.back(); // Go back in the history
    2. 次に、_location.hash_プロパティを設定します。前の手順で履歴に戻った場合、履歴エントリは上書きされます。


    フォールバック(最後)メソッドが常に履歴を置き換えるとは限りません。
    _location.hash == hash_の場合、次のいずれかが当てはまります。

    1. ハッシュはまだ変更されていないため、前のページに戻るのは意味がありません。
    2. ユーザーが元のページの状態に戻る可能性があります。 history.back();を使用すると、ページがアンロードされる可能性がありますが、これは望ましくありません。


    したがって、safeであるために、決してアンロードしませんハッシュが保存された元のハッシュと等しい場合のページ。

    注:ハッシュを変更する前に、このコードを実行することが重要です。ハッシュがすでに変更されている場合、スクリプトは信頼できなくなります。ユーザーは、保存されたhashと等しくない最初のハッシュ状態に移動できた可能性があります。その結果、history.back()はページをアンロードします。

35
Rob W

2番目のreplace-引数なしで、window.locationnewSubStr-メソッドを使用できます。これは、oldIEを含め、すべての既知のブラウザーで機能します。

function replaceHash(hash) {
  return window.location.replace(
    '#' + hash.replace(/^#/, '')
  );
}

ドキュメントに有効な要素( 仕様による )がある場合、ページはその要素にジャンプ/スクロールすることに注意してください。

22
yckart