Chrome onpopstate / pushState错误?

时间:2011-11-19 16:36:30

标签: javascript html5 google-chrome 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事件永远不会触发。 然后,当我单击浏览器中的后退按钮时,看起来多个popstate事件正在触发。看来,无论何时我使用浏览器导航按钮,每个应该触发的popstate事件都会同时发生。

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

  
    

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

  
     

popstate.html:13Sat 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(格林威治标准时间标准时间)

     

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

     
    

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

  
     

popstate.html:13Sat 2011年11月19日16:26:27 GMT + 0000(GMT标准时间)

     

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

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

  
    

加载页面

  
     

popstate.html:13Sat 2011年11月19日16:27:42 GMT + 0000(GMT标准时间)

     

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

     
    

单击新状态链接。控制台中没有任何内容。地址栏更改为/test/0.5458911096211523

         

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

  
     

popstate.html:13Sat 2011年11月19日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,但它永远不会触发推送状态。 如果我现在在浏览器中按下,我会得到:

  

popstate.html:13Sat 2011年11月19日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 2011年11月19日16:29:58 GMT + 0000(GMT标准时间)

     

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

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

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

提前感谢所有读过这一切的人,并为我提供一些启示。

2 个答案:

答案 0 :(得分:3)

当你去其他网页时,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
});

修改:这已经是a bug on the Chromium bug tracker

答案 1 :(得分:1)

if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1 !== true) {
    runpopState();
}

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

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

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