javascript Chrome onpopstate / pushState 错误?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8195502/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Chrome onpopstate / pushState bug?
提问by antriver
First of all I'm not entirely sure what I'm doing or expecting is right. There doesn't seem to be much documentation about this, but what I've read suggests that this should work.
首先,我不完全确定我在做什么或期待什么是正确的。似乎没有太多关于此的文档,但我读过的内容表明这应该有效。
I encountered some problems while trying to use history.pushState so I ended up making a demo page to see what was going wrong.
我在尝试使用 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>
When I click the 'new state' link, I'm expecting to see in the console that the onpopstate function has been fired and I'll see a new url (something like test/[number]).
当我单击“新状态”链接时,我希望在控制台中看到 onpopstate 函数已被触发,并且我会看到一个新的 url(类似于 test/[number])。
The location in the address bar in chrome does update, but the onpopstate event never fires. Then when I click the back button in the browser, it looks like multiple popstate events are firing. It appears that ever time I use the browser navigation buttons, every popstate event that should have fired is happening all at once.
chrome 地址栏中的位置会更新,但 onpopstate 事件永远不会触发。然后当我单击浏览器中的后退按钮时,看起来多个 popstate 事件正在触发。似乎每当我使用浏览器导航按钮时,应该触发的每个 popstate 事件都同时发生。
This is kind of hard to explain. Here's what I expect to see in the console.
这有点难以解释。这是我希望在控制台中看到的内容。
Load the page. Chrome fires the initial popstate event on page load
popstate.html:13Sat Nov 19 2011 16:23:48 GMT+0000 (GMT Standard Time)
popstate.html:14http://example.com/popstate.html
Click the 'new state' link. The location in the address bar updates to http://example.com/test/0.06458491436205804.
Sat Nov 19 2011 16:23:53 GMT+0000 (GMT Standard Time)
popstate.html:14http://example.com/test/0.06458491436205804
Click the back button in the browser. The url in the address bar returns to /popstate.html
popstate.html:13Sat Nov 19 2011 16:26:27 GMT+0000 (GMT Standard Time)
popstate.html:14http://example.com/popstate.html
加载页面。Chrome 在页面加载时触发初始 popstate 事件
popstate.html:13 周六 2011 年 11 月 19 日 16:23:48 GMT+0000(GMT 标准时间)
popstate.html:14http://example.com/popstate.html
单击“新状态”链接。地址栏中的位置更新为http://example.com/test/0.06458491436205804。
2011 年 11 月 19 日星期六 16:23:53 GMT+0000(GMT 标准时间)
popstate.html:14http://example.com/test/0.06458491436205804
单击浏览器中的后退按钮。地址栏中的 url 返回到 /popstate.html
popstate.html:13 周六 2011 年 11 月 19 日 16:26:27 GMT+0000(GMT 标准时间)
popstate.html:14http://example.com/popstate.html
That's what I'm expecting. Here's what I'm ACTUALLY seeing...
这就是我所期待的。这就是我真正看到的......
Load the page
popstate.html:13Sat Nov 19 2011 16:27:42 GMT+0000 (GMT Standard Time)
popstate.html:14http://example.com/popstate.html
Click the new state link. Nothing appears in console. Address bar changes to /test/0.5458911096211523
Click back button in browser. Address changes back to /popstate.html
popstate.html:13Sat Nov 19 2011 16:27:42 GMT+0000 (GMT Standard Time)
popstate.html:14http://example.com/popstate.html
popstate.html:13Sat Nov 19 2011 16:28:57 GMT+0000 (GMT Standard Time)
popstate.html:14http://example.com/popstate.html
加载页面
popstate.html:13 周六 2011 年 11 月 19 日 16:27:42 GMT+0000(GMT 标准时间)
popstate.html:14http://example.com/popstate.html
单击新状态链接。控制台中什么都没有出现。地址栏更改为 /test/0.5458911096211523
单击浏览器中的后退按钮。地址改回 /popstate.html
popstate.html:13 周六 2011 年 11 月 19 日 16:27:42 GMT+0000(GMT 标准时间)
popstate.html:14http://example.com/popstate.html
popstate.html:13 周六 2011 年 11 月 19 日 16:28:57 GMT+0000(GMT 标准时间)
popstate.html:14http://example.com/popstate.html
As you can see, it repeats the initial popstate and shows the return to /popstate.html, but it never fires for the pushed sate. If I now press forward in the browser, I get:
如您所见,它重复初始 popstate 并显示对 /popstate.html 的返回,但它从不为推送状态触发。如果我现在在浏览器中向前按,我会得到:
popstate.html:13Sat Nov 19 2011 16:27:42 GMT+0000 (GMT Standard Time)
popstate.html:14http://example.com/popstate.html
popstate.html:13Sat Nov 19 2011 16:28:57 GMT+0000 (GMT Standard Time)
popstate.html:14http://example.com/popstate.html
popstate.html:13Sat Nov 19 2011 16:29:58 GMT+0000 (GMT Standard Time)
popstate.html:14http://example.com/test/0.5458911096211523
popstate.html:13 周六 2011 年 11 月 19 日 16:27:42 GMT+0000(GMT 标准时间)
popstate.html:14http://example.com/popstate.html
popstate.html:13 周六 2011 年 11 月 19 日 16:28:57 GMT+0000(GMT 标准时间)
popstate.html:14http://example.com/popstate.html
popstate.html:13 周六 2011 年 11 月 19 日 16:29:58 GMT+0000(GMT 标准时间)
popstate.html:14http://example.com/test/0.5458911096211523
(They all appear again, here's a screenshot: http://img.ctrlv.in/4ec7da04e20d3.jpg)
(都又出现了,截图如下:http: //img.ctrlv.in/4ec7da04e20d3.jpg)
I don't know if I'm doing it wrong, my expectations are wrong, or this is actually a bug?
我不知道是我做错了,我的期望错了,还是这实际上是一个错误?
Thanks in advance to anyone who read all of this and can shed some light on it for me.
在此先感谢任何阅读了所有这些内容并且可以为我解释的人。
采纳答案by pimvdb
Chrome's console.log
cannot handle things nicely when you're going to other pages. You can confirm this because it logs several things at once with other timestamps (which cannot be possible). You'd better use $("body").append
to log here (or appending to some other element).
console.log
当您访问其他页面时,Chrome无法很好地处理问题。您可以确认这一点,因为它使用其他时间戳(这是不可能的)同时记录几件事。您最好$("body").append
在此处登录(或附加到其他一些元素)。
Secondly, when you pusha state, then obviously it is not popped, so the popstate
event is not triggered. If you want to trigger the onpopstate
handler when you're pushing a state as well, you can create a simple wrapper like this: http://jsfiddle.net/vsb23/2/.
其次,当你推送一个状态时,显然它没有 popped,所以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
});
Edit:This is already a bug on the Chromium bug tracker.
编辑:这已经是 Chromium 错误跟踪器上的错误。
回答by TaylorMac
if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1 !== true) {
runpopState();
}
function runpopState() {
alert("POP STATE");
}
window.onpopstate = function () {
runpopState();
};
Until they fix the bug, a solution like this will suffice.
在他们修复错误之前,这样的解决方案就足够了。