Chrome onpopstate/pushState bug?

发布于 2024-12-17 06:26:29 字数 3350 浏览 1 评论 0原文

首先,我不完全确定我正在做的或期待的事情是否正确。似乎没有太多关于此的文档,但我读过的内容表明这应该可行。

我在尝试使用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 事件永远不会触发。 然后,当我单击浏览器中的后退按钮时,似乎正在触发多个 popstate 事件。看来每当我使用浏览器导航按钮时,每个应该触发的 popstate 事件都会同时发生。

这有点难以解释。这是我期望在控制台中看到的内容。

<块引用>

加载页面。 Chrome 在页面加载时触发初始 popstate 事件

popstate.html:132011 年 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:132011 年 11 月 19 日星期六 16:26:27 GMT+0000(GMT 标准时间)

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

就是这样我期待着。 这就是我实际看到的......

<块引用>

加载页面

popstate.html:132011 年 11 月 19 日星期六 16:27:42 GMT+0000(GMT 标准时间)

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

<块引用>

单击新状态链接。控制台中什么也没有出现。地址栏更改为/test/0.5458911096211523

单击浏览器中的后退按钮。地址改回/popstate.html

popstate.html:132011 年 11 月 19 日星期六 16:27:42 GMT+0000(GMT 标准时间)

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

popstate.html:132011 年 11 月 19 日星期六 16:28:57 GMT+0000(GMT 标准时间)

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

正如您所看到的,它重复初始 popstate 并显示返回到 /popstate.html,但它永远不会触发推送状态。 如果我现在在浏览器中前进,我会得到:

popstate.html:132011 年 11 月 19 日星期六 16:27:42 GMT+0000(GMT 标准时间)

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

popstate.html:132011 年 11 月 19 日星期六 16:28:57 GMT+0000(GMT 标准时间)

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

popstate.html:132011 年 11 月 19 日星期六 16:29:58 GMT+0000(GMT 标准时间)

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

(它们都再次出现,这是一个屏幕截图:http://img.ctrlv.in/4ec7da04e20d3.jpg

我不知道是我做错了,我的期望是错误的,还是这实际上是一个错误?

预先感谢阅读所有这些内容并能为我提供一些线索的人。

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.

<!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]).

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.

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

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

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.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

(They all appear again, here's a screenshot: 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半透明的墙 2024-12-24 06:26:29

当您转到其他页面时,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 bug 上的 bug跟踪器

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).

Secondly, when you push a 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/.

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.

绝不服输 2024-12-24 06:26:29
if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1 !== true) {
    runpopState();
}

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

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

在他们修复错误之前,这样的解决方案就足够了。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文