Как заменить хэш местоположения и сохранить только последнюю запись истории?

я использую jQuery барбекю плагин для отслеживания прогресса пользователей на странице. Однако я хочу создать только 1 дополнительную запись в истории пользователя, а не одну для каждого изменения хэша.

Я пробовал jQuery.bbq.pushState и merge_mode методы, без успеха: новые записи истории по-прежнему добавляются:

jQuery.bbq.pushState({ sort: encodeURIComponent(sort) });

Я также пробовал location.replace(), но это не работает в Safari 5.1.2.

location.replace('#' + encodeURIComponent(sort))

Что такое кросс-браузер решение изменить хэш, не добавляя слишком много записей в историю?

2 ответов


во-первых, я показываю определения функции replaceHash, который принимает только один аргумент: новый хэш местоположения. Подробное объяснение логики можно найти в нижней части ответа.

код:

// 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 поддерживается, функция всегда будет заменять текущий хэш, без каких-либо побочных эффектов.
  • в противном случае, ссылка (hash) до самого первого location.hash создается свойство и определяется следующая функция:

    1. если location.hash != hash, тогда мы точно знаем, что состояние истории, по крайней мере, за первой страницей. Мы можем спокойно вернуться в историю, не разгружая страницу. history.back(); // Go back in the history.
    2. затем location.hash собственность. Если мы вернемся в историю на предыдущем шаге, запись истории перезаписывается.


    резервный (последний) метод может не всегда заменяют историю:
    Когда location.hash == hash, верно одно из следующих утверждений:

    1. хэш еще не изменился, поэтому нет смысла возвращаться к предыдущей странице.
    2. возможно, что пользователь перешел назад, в исходное состояние страницы. Если мы используем history.back();, страница может быть выгружена, что нежелательно.


    Итак,безопасное, мы никогда выгрузить страницы когда хэш равен сохраненному исходному хэшу.

    Примечание: важно запустить этот код перед изменением хэша. Когда хэш уже был изменен, скрипт больше не является надежным. Пользователь мог перейти в самое первое состояние хэша, которое не равно сохраненному hash. Следовательно, history.back() выгружает страницы.


можно использовать replace-способ от window.location, без второго newSubStr-аргумент. Это работает во всех известных браузерах, даже Олди:

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

обратите внимание, что если есть действительный элемент (согласно спецификации) в документе, страница будет прыгать/выделите его.