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

Я использую плагин jQuery BBQ для отслеживания продвижения пользователей по странице. Однако я хочу создать только 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-argument. Это работает во всех известных браузерах, даже oldIE:

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

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

Другие вопросы по тегам