Ошибка 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();
};
Пока они не исправят ошибку, такого решения будет достаточно.