嘛,起因是黑子大叔在微博上的一條@信息,找起了這個的實現(xiàn),看了一圈google的中文信息內似乎還沒有怎么提到這個的內容,就發(fā)表上來。
詳細效果就是類似于用Firefox4+/Chrome 5+/Safari 5+/Opera 11.5+登錄新浪微博后看到的個人時間軸,在翻頁時可以觀察到這個效果,地址欄URL變動,但是頁面沒有刷新,用firebug觀察也觀察不到刷新整個頁面,只有ajax請求的翻頁數(shù)據。從先前的理解來說,URL的修改必然引起(請注意我不是在說通過錨點修改)瀏覽器重載頁面,但利用HTML5新加入的history.pushState();和history.replaceState();可以完全自己維護一個歷史記錄列表繞開歷史記錄完全由瀏覽器控制的機制,從而實現(xiàn)比錨點更加完美的一種頁內更新的體驗。
代碼方面很簡單,只要在需要修改url的地方插入一行:
window.history.pushState({"html":response.html,"pageTitle":response.pageTitle}, 'title', urlPath);
//三個參數(shù),分別為:狀態(tài)對象,標題(目前被瀏覽器忽略),地址
即可在歷史記錄里面產生一個新的歷史記錄(另一個replaceState方法參數(shù)完全相同,只是替代掉當前的狀態(tài))。
在體驗上,非常接近于使用錨點(window.location = “#foo”;),但是mozilla的文檔提出了以下三點好處:
新的URL可以是和原始頁面URL同域下的任何URL,如果用錨點,只能更新#后面的部分
僅在需要時更新URL,錨點的歷史記錄在相同時不會創(chuàng)建(即當前已經是”#foo”的情況下,如果再將當前頁面錨點設置為”#foo”,不會產生新的歷史記錄)
可以記錄下任意類型的數(shù)據,使用錨點的話將要自己維護一份歷史數(shù)據列表或者把數(shù)據轉碼到一個字符串里
(翻譯&描述的有點別扭,見笑了,不過其實應該自己也能體會到這些好處才是)
我自己實現(xiàn)的一個例子:
http://vifix.cn/atelier/demos/html5-update-browser-url-without-reloading-page
代碼:
<?php
if(!isset($_REQUEST['page'])){
    $page = 1;
}
else{
    $page = intval($_REQUEST['page']);
}
 
if(isset($_REQUEST['ajaxload'])){
    echo "第{$page}頁的內容";
    die;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>HTML5 修改瀏覽器url而不刷新頁面</title>
<script type="text/javascript">
var domLoaded = function(){
    if(ua != null && ua[1] < 10){
        alert('您的瀏覽器不支持');
        return ;
    }
 
    if(location.href.indexOf("?") > -1){
        var urlparts = location.href.match(/(.+?)\?.+/i);
        var urlbase = urlparts[1];
    }
    else{
        var urlbase = location.href;
    }
    var page = <?php echo $page;?>;
    var ua = window.navigator.userAgent.match(/msie (\d\.\d)/i);
    var content = document.getElementById("content");
    var loading = document.getElementById("loading");
 
    window.history.replaceState(
        {
            content:content.innerHTML,
            page:page
        },
        page,
        urlbase + (page > 1 ? '?page=' + page : '' )
    );
 
    var ajax = new XMLHttpRequest();
    var ajaxCallback = function(){
        if(ajax.readyState == 4){
            loading.style.display = 'none';
            content.innerHTML = ajax.responseText;
            window.history.pushState(
                {
                    content:content.innerHTML,
                    page:page
                },
                page,
                urlbase + "?page=" + page
            );
            next.href = urlbase + "?page=" + (page + 1);
        }
    };
 
    var next = document.getElementById('next');
    var nextClickEvent = function(event){
        if(loading.style.display != 'block'){
            loading.style.display = 'block';
            page++;
            ajax.open('GET', urlbase + '?page=' + page + '&ajaxload=on', true);
            ajax.onreadystatechange = ajaxCallback;
            ajax.send('');
            event.preventDefault();
        }
    };
    next.addEventListener('click', nextClickEvent, false);
 
    var popstate = function(){
        content.innerHTML = history.state.content;
        page = history.state.page;
    };
    window.addEventListener('popstate', popstate, false);
};
 
try{
    window.addEventListener('DOMContentLoaded', domLoaded, false);
}
catch(e){
    alert('您的瀏覽器不支持');    
}
</script>
</head>
<body>
    <p id="content">
        <?php echo "第{$page}頁的內容";?>
    </p>
    <p>
        <a id="next" href="?page=<?php echo $page+1;?>">下一頁</a>
    </p>
    <div id="loading" style="display:none;">
        加載中
    </div>
</body>
</html>
mozilla的文檔
https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
stackoverflow上的相關問題:
http://stackoverflow.com/questions/3338642/updating-address-bar-with-new-url-without-hash-or-reloading-the-page
http://stackoverflow.com/questions/824349/modify-the-url-without-reloading-the-page