HTML5 history API實踐

呂大豹發表於2013-08-12

一、history API知識點總結

  在HTML4中,我們已經可以使用window.history物件來控制歷史記錄的跳轉,可以使用的方法包括:

  history.forward();//在歷史記錄中前進一步

  history.back();//在歷史記錄中後退一步

  history.go(n);//在歷史記錄中跳轉n步,n=0則重新整理當前頁,n=-1則後退一步

  在HTML5中,又新增了四個可用的API,包括:

history.pushState(data[,title][,url]);//向歷史記錄中追加一條記錄,data是一個js物件,可以是任何格式的json資料,title引數暫時不起作用,我親自試了也確實如此。引數url是指位址列中的地址值,不填則保持當前url

history.replaceState(data[,title][,url]);//替換當前頁在歷史記錄中的資訊。引數與上面一致。

history.state;//是一個屬性,可以得到當前頁的state資訊。

window.onpopstate;//是一個事件,在點選瀏覽器後退按鈕或js呼叫forward()、back()、go()時觸發。監聽函式中可傳入一個event物件,event.state即為通過pushState()或replaceState()方法傳入的data引數。

二、新API在實際中的使用

  知道了有這些新API,我們可以如何利用它們呢?以下是兩個相關的使用案例:

  ① 還原ajax程式中瀏覽器後退按鈕的功能。其實這個應用已經被大家廣泛熟知了,由於ajax的固有缺點(無法使用瀏覽器後退按鈕返回上一頁),通過在發起ajax請求時在歷史記錄中新增一條記錄並修改位址列中的值,來模擬一個正常的跳轉,同時仍然保留ajax非同步載入的優點。方法如下:

var title = '另一篇隨筆';
var url = 'http://www.cnblogs.com/lvdabao/p/另一篇隨筆.html';
var state = {title:title,url:url};
history.pushState(state,title,url);//第三個引數url的值將會出現在位址列

   點選下面按鈕,注意位址列的變化:

    

  ②儲存非同步請求的引數,在頁面返回時重現原來頁面上的動態資料。具體需求是這樣的:比如我們處在一個搜尋結果列表頁,頁面上的內容是根據搜尋條件動態得到的,我們可以點選其中一項進行詳情預覽(發ajax請求),在詳情頁點選“返回”時,我們希望原來的搜尋資料還在,而不是變回列表頁初始載入時的資料。以前,我們可以用回傳引數的方式解決這樣的需求,但那樣做的缺點就是有大量的資料需要來回傳遞,如果頁面層級較多,將會很不方便。那麼現在,我們結合使用history的onpopstate事件,便可用完成這樣的功能。舉例來說:

  我要做一個介紹HTML5 history的頁面,index.html中的程式碼如下:

<body>
<p>HTML5 history API 介紹</p>
<a href="javascript:void(0)" id="pushstate">history.pushState(data, title [, url])</a>&nbsp;&nbsp;&nbsp;&nbsp;
<a href="javascript:void(0)" id="replacestate">history.replaceState(data, title [, url]) </a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="javascript:void(0)" id="onpopstate">window.onpopstate</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="javascript:void(0)" id="back">返回</a>
<div id="loaddiv"></div>
<script>

$(function(){
    
    var loaddiv = $('#loaddiv');
  
  //點選不同的連結,分別在loaddiv中載入不同的內容
$(
'#pushstate').click(function(){ loaddiv.load('1.php?stype=push'); history.pushState({title:'push',url:'1.php?stype=push'}); }); $('#replacestate').click(function(){ loaddiv.load('1.php?stype=replace'); history.pushState({title:'replace',url:'1.php?stype=replace'}); }); $('#onpopstate').click(function(){ loaddiv.load('1.php?stype=onpop'); history.pushState({title:'onpop',url:'1.php?stype=onpop'}); });

  //點選返回,讓瀏覽器後退一步 $(
'#back').click(function(){ history.back(); });
  //兼聽popstate事件,可以取到e.state的值,其中儲存了你呼叫pushState方法時傳入的資料,根據資料中的url非同步載入相應內容。便實現了點選返回時頁面上的資料保持是上次載入過的。 window.onpopstate
= function(e){ if(e.state){ loaddiv.load(e.state.url); } } }); </script> </body>

  我要分別介紹history的三個新特性,通過呼叫jquery的load方法來非同步載入,傳送一個請求到1.php,同時傳遞對應的引數。後臺接受到請求後根據不同的引數返回不同的資料,php程式碼如下:

<?php
$type = $_REQUEST['stype'];
switch($type){
    case 'push' :  
    echo 'history.pushState(data, title [, url]):往歷史記錄堆疊頂部新增一條記錄;data會在onpopstate事件觸發時作為引數傳遞過去;title為頁面標題,當前所有瀏覽器都會 忽略此引數;url為頁面地址,可選,預設為';
    break;
    case 'replace' :  
    echo 'history.replaceState(data, title [, url]) :更改當前的歷史記錄,引數同上';
    break;
    case 'onpop' :  
    echo 'window.onpopstate:響應pushState或replaceState的呼叫;';
    break;
    }
?>

  我在這裡無法上傳php檔案,你可以將程式碼複製到本地伺服器測試。如此一來,便可以實現像github那樣的頁面載入機制。

  以上便是我所見到過的關於history的兩點使用方法。有發現錯誤歡迎指正,其他觀點也歡迎交流。

相關文章