Как заменить хеш местоположения и сохранить только последнюю запись в истории?
Я использую плагин 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
свойство создано, и определена следующая функция:- Если
location.hash != hash
тогда мы точно знаем, что состояние истории, по крайней мере, прошло после просмотра первой страницы. Мы можем смело возвращаться в историю, не разгружая страницу.history.back(); // Go back in the history
, - Затем установите
location.hash
имущество. Если мы вернулись в историю на предыдущем шаге, запись истории будет перезаписана.
Резервный (последний) метод не всегда может заменить историю:
когдаlocation.hash == hash
любое из следующего верно:- Хеш еще не изменился, поэтому нет смысла возвращаться на предыдущую страницу.
- Возможно, что пользователь перешел назад, к исходному состоянию страницы. Если мы используем
history.back();
страница может быть выгружена, что нежелательно.
Поэтому, чтобы быть в безопасности, мы никогда не выгружаем страницу, когда хэш равен сохраненному оригинальному хешу.Примечание. Важно запустить этот код до изменения хеша. Когда хеш уже изменен, скрипт больше не является надежным. Пользователь мог перейти к самому первому состоянию хеша, которое не равно сохраненному
hash
, Как следствие,history.back()
выгружает страницу.- Если
Вы могли бы использовать replace
-метод из window.location
без второго newSubStr
-argument. Это работает во всех известных браузерах, даже oldIE:
function replaceHash(hash) {
return window.location.replace(
'#' + hash.replace(/^#/, '')
);
}
Обратите внимание, что если в документе есть действительный элемент ( согласно спецификации), страница перейдет к нему.