Ошибка Chrome onpopstate/pushState?

Прежде всего, я не совсем уверен, что я делаю или ожидаю, это правильно. Там, похоже, не так много документации об этом, но то, что я прочитал, предполагает, что это должно работать.

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

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js" ></script>
<script>

window.onpopstate = function()
{
    var d = new Date;
    console.log(d.toString());
    console.log(document.location.href);
};

$(document).ready(function()
{

    $('#push').click(function()
    {
        var rand = Math.random();
        history.pushState( {'number':rand} , 'Test '+rand , '/test/'+rand );
        return false;
    });

});

</script>

</head>

<body>

<a href="#" id="push">New state</a>

</body>
</html>

Когда я нажимаю ссылку "новое состояние", я ожидаю увидеть в консоли, что функция onpopstate была уволена, и я увижу новый URL-адрес (что-то вроде test/[number]).

Расположение в адресной строке в chrome обновляется, но событие onpopstate никогда не срабатывает. Затем, когда я нажимаю кнопку "Назад" в браузере, похоже, что несколько всплывающих событий запускаются. Похоже, что когда бы я ни использовал навигационные кнопки браузера, каждое всплывающее событие, которое должно было быть запущено, происходит сразу.

Это трудно объяснить. Вот что я ожидаю увидеть на консоли.

Загрузите страницу. Chrome запускает начальное событие popstate при загрузке страницы

popstate.html: 13Sat Nov 19 2011 16:23:48 GMT + 0000 (GMT стандартное время)

popstate.html: 14http://example.com/popstate.html

Нажмите ссылку "новое состояние". Расположение в адресной строке обновляется до http://example.com/test/0.06458491436205804.

Сб Ноя 19 2011 16:23:53 GMT + 0000 (GMT Стандартное время)

popstate.html: 14http://example.com/test/0.06458491436205804

Нажмите кнопку "Назад" в браузере. URL-адрес в адресной строке возвращается в /popstate.html

popstate.html: 13Sat Nov 19 2011 16:26:27 GMT + 0000 (GMT Стандартное время)

popstate.html: 14http://example.com/popstate.html

Это то, что я ожидаю. Вот что я НАСТОЯТЕЛЬНО вижу...

Загрузите страницу

popstate.html: 13Sat Nov 19 2011 16:27:42 GMT + 0000 (GMT Стандартное время)

popstate.html: 14http://example.com/popstate.html

Нажмите ссылку нового состояния. В консоли ничего не отображается. Изменение адресной строки в /test/ 0.5458911096211523

     

Нажмите кнопку "Назад" в браузере. Возврат адреса обратно в /popstate.html

popstate.html: 13Sat Nov 19 2011 16:27:42 GMT + 0000 (GMT Стандартное время)

popstate.html: 14http://example.com/popstate.html

popstate.html: 13Sat Nov 19 2011 16:28:57 GMT + 0000 (GMT Стандартное время)

popstate.html: 14http://example.com/popstate.html

Как вы можете видеть, он повторяет начальную popstate и показывает возврат в /popstate.html, но он никогда не срабатывает для нажатого sate. Если я сейчас перейду в браузере, я получаю:

popstate.html: 13Sat Nov 19 2011 16:27:42 GMT + 0000 (GMT Стандартное время)

popstate.html: 14http://example.com/popstate.html

popstate.html: 13Sat Nov 19 2011 16:28:57 GMT + 0000 (GMT Стандартное время)

popstate.html: 14http://example.com/popstate.html

popstate.html: 13Sat Nov 19 2011 16:29:58 GMT + 0000 (GMT Стандартное время)

popstate.html: 14http://example.com/test/0.5458911096211523

(Все они появляются снова, вот скриншот: http://img.ctrlv.in/4ec7da04e20d3.jpg)

Я не знаю, ошибаюсь ли я, мои ожидания ошибочны, или это на самом деле ошибка?

Спасибо заранее всем, кто прочитал все это и может пролить свет на него для меня.

Ответ 1

Chrome console.log не может хорошо обрабатывать вещи, когда вы переходите на другие страницы. Вы можете подтвердить это, потому что он регистрирует несколько вещей одновременно с другими отметками времени (что невозможно). Вам лучше использовать $("body").append для входа сюда (или добавления к другому элементу).

Во-вторых, когда вы нажимаете состояние, то, очевидно, оно не выставляется, поэтому событие popstate не запускается. Если вы хотите запускать обработчик onpopstate, когда вы нажимаете состояние, вы можете создать простую оболочку, подобную этой: http://jsfiddle.net/vsb23/2/.

function load(url, state) { // logging function; normally load AJAX stuff here
    $("pre").append(new Date
                    + "\n" + url
                    + "\n" + JSON.stringify(state) // to log object as string
                    + "\n\n");
}

function pushState(data, title, url) {
    history.pushState(data, title, url);
    load(location.href, data); // call load function when pushing as well
}

window.onpopstate = function(e) {
    load(location.href, e.state);
};

$("button").click(function() {
    pushState({foo: "bar"}, "test", "/test?a=b"); // sample push
});

Изменить: Это уже ошибка в отслеживателе ошибок Chromium.

Ответ 2

if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1 !== true) {
    runpopState();
}

function runpopState() {
    alert("POP STATE");
}

window.onpopstate = function () {
    runpopState();
};

Пока они не исправят ошибку, такого решения будет достаточно.