Можете ли вы использовать хэш-навигацию, не затрагивая историю?

100

Боюсь, это может быть невозможно, но есть ли способ изменить хеш-значение URL-адреса, не оставляя записи в истории браузера и без перезагрузки ? Или сделать аналог?

Что касается специфики, я разрабатывал базовую хеш-навигацию по следующим строкам:

//hash nav -- works with js-tabs
var getHash = window.location.hash;
var hashPref = "tab-";
function useHash(newHash) {
    //set js-tab according to hash
    newHash = newHash.replace('#'+hashPref, '');
    $("#tabs li a[href='"+ newHash +"']").click();
}
function setHash(newHash) {
    //set hash according to js-tab
    window.location.hash = hashPref + newHash;

    //THIS IS WHERE I would like to REPLACE the location.hash
    //without a history entry

}
    // ... a lot of irrelavent tabs js and then....

    //make tabs work
    $("#tabs.js-tabs a").live("click", function() {
        var showMe = $(this).attr("href");
        $(showMe).show();
        setHash(showMe);
        return false;
    });
    //hash nav on ready .. if hash exists, execute
    if ( getHash ){
        useHash(getHash);
    }

Очевидно, с использованием jQuery. Идея заключается в том, что в этом конкретном случае 1) заставляя пользователя возвращаться к каждому изменению вкладки, можно эффективно `` сломать кнопку возврата '', накапливая ненужные ссылки, и 2) не удерживать, на какой вкладке они сейчас находятся, если они нажимают обновление, раздражение.


источник
Почему вы хотите менять хеш, если не хотите отслеживать историю? : |
Ionuț Staicu
10
Потому что при обновлении было бы лучше представить пользователю вкладку, на которой он был, но поскольку они могут переключаться между вкладками, это излишне переполняет их историю записями, делая кнопку возврата фактически менее полезной. Это всего лишь пример - это может быть в любое время, когда вам нужно сохранить временное состояние, но вы не хотите полагаться на файлы cookie или заполнять ими временный файл пользователя. Когда вы обновляете, содержимое js остается таким, каким вы его оставили - вы не покинули страницу, и это не точка перехода или псевдостраница, поэтому запись в истории может только мешать стандартной навигации.

Ответы:

95

location.replace("#hash_value_here");отлично работал у меня, пока я не обнаружил, что он не работает в IOS Chrome. В этом случае используйте:

history.replaceState(undefined, undefined, "#hash_value")

history.replaceState () работает точно так же, как history.pushState (), за исключением того, что replaceState () изменяет текущую запись в истории, а не создает новую.

Не забудьте сохранить #или последняя часть URL-адреса будет изменена.

Люсия
источник
3
Абсолютно правильный путь для современных браузеров; имейте в виду, что управление историей сеансов частичной поддержки имеет.
Мэтт
Я не понимаю, как это использовать. Должен ли я все еще использовать window.location.hash = 'my-hash';после history.replaceState(undefined, undefined, "#my-hash")?
Брэм Ванрой
2
@BramVanroy Нет, достаточно последнего.
Люсия
2
Если вы не используете селекторы: target ... тогда функции истории бесполезны, так как эта часть спецификации (взаимодействие css с историческими операциями), похоже, в настоящее время не определена, и стиль не пересчитывается при замене истории большинством / всеми браузерами.
morphles
@Luxiyalu, чем history.replaceStateотличается от location.replace?
Pacerier
99
location.replace("#hash_value_here"); 

Вышеупомянутое, похоже, делает то, что вам нужно.

Мэтт
источник
4
Это оно. А если у вас есть сегменты uri, location.replace (window.location + "#hash") сохранит их.
сеноворошилки
7
Продолжая этот метод, намного чище, хотелось бы, чтобы он был отмечен как правильный ответ.
Joeellis 02
14
window.location.replace(('' + window.location).split('#')[0] + '#' + hash);просто обновить хеш
johnstorm
1
Я тестирую его в Chrome 30 под Windows 8. Если я перейду в историю Chrome и выберу «Еще с этого сайта» под своим тестовым URL-адресом, я смогу увидеть все хэши, добавленные этим методом.
Alex Vang
1
Помните, что location.replace ('# hash_value_here') изменяет только хеш-фрагмент, а не путь, поэтому он не запускает загрузку страницы .... За исключением случаев, когда документ содержит базовый тег: <base href ="http://example.com/" /> если он содержит базовый тег , тогда, когда вы используете метод replace только с ведущими, "#hash_value_here"это будет выглядеть так, как если бы вы сказали `location.replace (' example.com/#hash_value_here' ). Это кажется очевидным, когда вы читаете это здесь, но это ошибка, когда вы находитесь на странице с фрагментом пути и не понимаете, что база установлена.
Тайлер Кастен
6

Изменить: прошло пару лет, и браузеры эволюционировали.

@ Luxiyalu в ответ это путь

- Старый ответ -

Я тоже думаю, что это невозможно (в настоящее время). Но зачем вам менять хеш-значение, если вы не собираетесь его использовать?

Я считаю, что основная причина, по которой мы используем хеш-значение в качестве программистов, заключается в том, чтобы позволить пользователю добавлять наши страницы в закладки или сохранять состояние в истории браузера. Если вы не хотите ничего из этого делать, просто сохраните состояние в переменной и работайте оттуда.

Я думаю, что причина использования хеша заключается в том, чтобы работать со значением, которое находится вне нашего контроля. Если вам это не нужно, то это, вероятно, означает, что у вас все под вашим контролем, поэтому просто сохраните состояние в переменной и работайте с ним. (Мне нравится повторяться)

Я надеюсь, что это помогает вам. Может, у твоей проблемы есть более простое решение.

ОБНОВЛЕНИЕ: Как насчет этого:

  1. Настройте первый хэш и убедитесь, что он сохраняется в истории браузера.
  2. Когда будет выбрана новая вкладка, сделайте это window.history.back(1), это вернет историю из вашего первого хэша инициализации.
  3. Теперь вы устанавливаете новый хеш, поэтому табуляция сделает только одну запись в истории.

Вам, вероятно, придется использовать некоторые флаги, чтобы знать, можно ли «удалить» текущую запись, вернувшись назад, или вы просто пропустите первый шаг. И чтобы убедиться, что ваш метод загрузки "хеша" не выполняется, когда вы принудительно загружаете файл history.back.

гузарт
источник
Вполне возможно, что мне не хватает чего-то базового (истощение - хорошее оправдание, я соглашусь с этим), но вы говорите, что я могу установить переменную, которая сохранит свое измененное значение при перезагрузке? Кроме печенья? (Печенья почему-то кажутся излишними ..) Может быть, это было непонятно. Я буду использовать хеш-значение - особенно при перезагрузке. Спасибо за ответ!
Чтобы прояснить мое пояснение: если пользователь нажимает перезагрузку. Вот для чего нужен хеш. Я все еще пытаюсь избежать перезагрузки при обычном использовании (изменение / переход по вкладкам).
Хорошо, поэтому после перезагрузки вы будете использовать некоторые значения для информации. К сожалению, хеш-значение будет выбрано историей некоторых браузеров. Извините за это, но, судя по моему опыту, лучше всего использовать файлы cookie. Если вы хотите что-то, что история браузера не обнаруживает, но, к сожалению, сохраняет файлы cookie после перезагрузки. Если пользователь щелкает ссылку, вы можете настроить ссылку как query ( ?mystate=greatness), даже если она не обязательно должна быть ajax, вы можете сохранить информацию для чтения javascript при инициализации запроса.
guzart
Да, хеш предназначен для сохранения информации о пользователе после перезагрузки, но проблема для вас в том, что некоторые браузеры сохраняют эти изменения в истории, именно так они и работают ... :(
guzart
Ага, думаю, ты прав. Ах хорошо. (Хотел бы быть доказанным каким-то другим методом или чем-то еще.)
-1

Вы всегда можете создать прослушиватель событий, чтобы улавливать события щелчка по гиперссылке, а в функции обратного вызова поместите e.preventDefault (), что должно помешать браузеру вставить его в историю.

Айман Фархат
источник