【问题标题】:Chrome onpopstate / pushState bug?Chrome onpopstate / pushState 错误?
【发布时间】:2012-01-01 23:44:28
【问题描述】:

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

我在尝试使用 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

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

提前感谢所有阅读了所有这些内容并能为我提供一些启示的人。

【问题讨论】:

    标签: javascript html google-chrome pushstate


    【解决方案1】:

    Chrome 的console.log 在您访问其他页面时无法很好地处理事情。您可以确认这一点,因为它使用其他时间戳一次记录几件事(这是不可能的)。您最好使用$("body").append 在此处登录(或附加到其他元素)。

    其次,当你push一个状态时,很明显它没有弹出,所以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
    });
    

    编辑:这已经是a bug on the Chromium bug tracker

    【讨论】:

    • 好的,谢谢。我会尝试以不同的方式记录它,看看我得到了什么。第二部分是我正在寻找的关键。我很困惑,因为在 mozilla 文档(我找到的唯一简洁资源)中,它说“每次活动历史条目更改时都会向窗口发送一个 popstate 事件。”对我来说,当你推动/替换一个状态时,这听起来也会触发。
    • 日志记录成功了。现在一切都变得更有意义了。我无法理解使用控制台时发生了什么。
    • @Anthony Kuske:我认为这是一个错误,因为通常在导航时控制台会被清除,但历史 API 实际上不会进行真正的导航,同时仍会更改它无法处理的 URL。
    【解决方案2】:
    if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1 !== true) {
        runpopState();
    }
    
    function runpopState() {
        alert("POP STATE");
    }
    
    window.onpopstate = function () {
        runpopState();
    };
    

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

    【讨论】:

      猜你喜欢
      • 2012-06-19
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-27
      • 2011-04-22
      • 1970-01-01
      • 2011-06-07
      相关资源
      最近更新 更多