Ошибка Chrome onpopstate / pushState? - PullRequest
7 голосов
/ 19 ноября 2011

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

Я столкнулся с некоторыми проблемами при попытке использовать 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: 13 сентября 19 ноября 16:23:48 GMT + 0000 (стандартное время GMT)

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

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

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

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

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

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

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

Это то, что я ожидаю. Вот что я на самом деле вижу ...

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

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

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

Нажмите на ссылку нового состояния. Ничего не появляется в консоли. Адресная строка меняется на /test/0.5458911096211523

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ответы [ 2 ]

3 голосов
/ 19 ноября 2011

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 .

1 голос
/ 02 июля 2012
if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1 !== true) {
    runpopState();
}

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

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

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

...