Пример history.replaceState ()?

86

Может ли кто-нибудь дать рабочий пример для history.replaceState? Это то, что w3.org говорит:

history . replaceState(data, title [, url ] )

Обновляет текущую запись в истории сеансов, чтобы иметь заданные данные, заголовок и, если предоставлено, а не null, URL.

Update:

Это отлично работает:

history.replaceState( {} , 'foo', '/foo' );

Url меняется, но название не меняется. Это ошибка или я чего-то не хватает? Протестировано на последнем Chrome.

  • 3
    Я обычно не добавляю дополнительные библиотеки для вопросов JavaScript, но в этом случае я сделаю исключение. Библиотека History.js - это небольшая оболочка, которая устраняет множество странных ошибок в API History в современных браузерах. Он даже обеспечивает дополнительную поддержку старых версий IE.
  • 2
    У MDN довольно хорошая рецензия на управление историей браузера
Показать ещё 5 комментариев
Теги:

7 ответов

52

Действительно, это ошибка, хотя и преднамеренная в течение 2 лет. Проблема кроется в некоторых нечетких спецификациях и сложности, когда задействуются document.title и назад/вперед.

См. ссылку на ошибку Webkit и Mozilla. Также Opera по внедрению API истории заявила, что не использует параметр title и, вероятно, до сих пор этого не делает.

В настоящее время второй аргумент pushState и replaceState - заголовок записи истории - не используется в реализации Opera, но может быть в один день.

Потенциальное решение

Единственное, что я вижу, это изменить элемент заголовка и вместо него использовать pushState:

document.getElementsByTagName('title')[0].innerHTML = 'bar';
window.history.pushState( {} , 'bar', '/bar' );
  • 0
    Для пользователей jquery .. попробуйте $ ("title"). Html (_title);
  • 2
    это может привести к тому, что пользователям потребуется «дважды щелкнуть» кнопку «назад» в зависимости от того, как вы это реализовали. Более простое решение может состоять в том, чтобы продолжать использовать replaceState() и просто установить заголовок document.title = "title" вручную document.title = "title"
24

Вот минимальный, надуманный пример.

console.log( window.location.href );  // whatever your current location href is
window.history.replaceState( {} , 'foo', '/foo' );
console.log( window.location.href );  // oh, hey, it replaced the path with /foo

Существует больше replaceState(), но я не знаю, что именно вы хотите с ним делать.

  • 2
    URL-адрес меняется, но название не меняется .. протестировано с последним Chrome @trott
  • 4
    @Serjas Параметр title в replaceState() , насколько мне известно, игнорируется во всех браузерах.
9

history.pushState подталкивает текущее состояние страницы в стек истории и изменяет URL-адрес в адресной строке. Поэтому, когда вы возвращаетесь, это состояние (объект, который вы передали) возвращается вам.

В настоящее время это все, что он делает. Любые другие действия, такие как отображение новой страницы или изменение названия страницы, должны выполняться вами.

Спецификация W3C, которую вы связываете, представляет собой только черновик, и браузер может реализовать его по-разному. Firefox, например, полностью игнорирует параметр title.

Вот простой пример pushState, который я использую на своем веб-сайте.

(function($){
    // Use AJAX to load the page, and change the title
    function loadPage(sel, p){
        $(sel).load(p + ' #content', function(){
            document.title = $('#pageData').data('title');
        });
    }

    // When a link is clicked, use AJAX to load that page
    // but use pushState to change the URL bar
    $(document).on('click', 'a', function(e){
        e.preventDefault();
        history.pushState({page: this.href}, '', this.href);
        loadPage('#frontPage', this.href);
    });

    // This event is triggered when you visit a page in the history
    // like when yu push the "back" button
    $(window).on('popstate', function(e){
        loadPage('#frontPage', location.pathname);
        console.log(e.originalEvent.state);
    });
}(jQuery));
  • 27
    Почему принятый ответ объясняет «pushState» вместо «replaceState»?
  • 1
    @GiwrgosTsopanoglou: я ответил на это год назад, поэтому я не уверен, почему :-P В любом случае replaceState изменяет текущее состояние страницы. Позволяет изменить объект состояния и URL текущего состояния страницы.
Показать ещё 1 комментарий
3

посмотрите пример

window.history.replaceState({
    foo: 'bar'
}, 'Nice URL Title', '/nice_url');

window.onpopstate = function (e) {
    if (typeof e.state == "object" && e.state.foo == "bar") {
        alert("Blah blah blah");
    }
};

window.history.go(-1);

и выполните поиск location.hash;

2

Второй аргумент Название не означает Название страницы - это больше определение/информация для состояния этой страницы

Но мы все равно можем изменить заголовок, используя событие onpopstate, и передать имя заголовка не из второго аргумента, а как атрибут из первого параметра, переданного как объект

Ссылка: http://spoiledmilk.com/blog/html5-changing-the-browser-url-without-refreshing-page/

1

Согласно MDN History doc
Ясно, что второй аргумент для будущего используется не сейчас. Вы правы, что второй аргумент касается названия веб-страницы, но в настоящее время он игнорируется всеми основными браузерами.

В настоящее время Firefox игнорирует этот параметр, хотя он может использовать его в будущем. Передача пустой строки здесь должна быть безопасной против будущих изменений метода. Кроме того, вы можете передать короткий заголовок для состояния, в которое вы двигаетесь.

  • 0
    Второй аргумент не относится к заголовку веб-страницы - документ MDN, который вы связали, говорит: «Передайте короткий заголовок для состояния, в которое вы переходите». , Это согласуется с документацией по интерфейсу истории W3C, в которой говорится: «Переносит данные в историю сеанса с указанным заголовком» . Данные в этой фразе являются данными о состоянии , поэтому заголовок снова относится к состоянию (данным).
0

Я действительно хотел ответить на ответ @Sev.

Сев прав, внутри window.history.replaceState

есть ошибка.

Чтобы исправить это, просто перепишите конструктор, чтобы установить заголовок вручную.

var replaceState_tmp = window.history.replaceState.constructor;
window.history.replaceState.constructor = function(obj, title, url){
    var title_ = document.getElementsByTagName('title')[0];
    if(title_ != undefined){
        title_.innerHTML = title;
    }else{
        var title__ = document.createElement('title');
        title__.innerHTML = title;
        var head_ = document.getElementsByTagName('head')[0];
        if(head_ != undefined){
            head_.appendChild(title__);
        }else{
            var head__ = document.createElement('head');
            document.documentElement.appendChild(head__);
            head__.appendChild(title__);
        }
    }
    replaceState_tmp(obj,title, url);
}
  • 1
    Не делай этого. Перезапись функций по умолчанию - очень плохой стиль
  • 2
    Что еще вы предлагаете, когда вам нужно исправить эту ошибку?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню