操縱歷史,利用HTML5 History API實現無刷新跳轉

寫在前面

有一次在上點點網的時候,發現登陸、註冊動畫效果非常華麗,但讓我感到震驚的是頁面竟能夠實現無刷新跳轉(已改版,觀看此效果可以猛擊此處:GitHub閱FM),回顧了所學的前端知識,似乎沒有任何技術可以實現這一點,於是百度搜羅了一下,才發現這原來是使用HTML5中History API實現的效果,但奈何一直未曾派上用場。直到博客改版時,纔將這一技術應用起來。

 

HTML4中的History API

history這個東西大家應該都不陌生,我們經常使用history.back(-1)來實現後退功能,具體的屬性和方法如下:

屬性

  1. length 歷史的項數。JavaScript 所能管到的歷史被限制在用瀏覽器的“前進”“後退”鍵可以去到的範圍。本屬性返回的是“前進”和“後退”兩個按鍵之下包含的地址數的和。

方法

  1. back() 後退,跟按下“後退”鍵是等效的。
  2. forward() 前進,跟按下“前進”鍵是等效的。
  3. go() 用法:history.go(x);在歷史的範圍內去到指定的一個地址。如果 x < 0,則後退 x 個地址,如果 x > 0,則前進 x 個地址,如果 x == 0,則刷新現在打開的網頁。history.go(0) 跟 location.reload() 是等效的。

HTML5中的History API

  1. history.pushState(data, title [, url]):往歷史記錄堆棧頂部添加一條記錄;data會在onpopstate事件觸發時作爲參數傳遞過去;title爲頁面標題,當前所有瀏覽器都會忽略此參數;url爲頁面地址,可選,缺省爲當前頁地址。
  2. history.replaceState(data, title [, url]) :更改當前的歷史記錄,參數同上。
  3. history.state:用於存儲以上方法的data數據,不同瀏覽器的讀寫權限不一樣。

瀏覽器兼容性

API Chrome Firefox(Geko) Internet Explorer Opera Safari
pushState, replaceState 5 4.0(2.0) 11.50 5.0
history.state 4.0(2.0) 11.50

下面是一段檢測瀏覽器是否支持History API的代碼:

  1. function supports_history_api(){
  2.         return !!(window.history && history.pushState);
  3. }

爲什麼要使用History API

在AJAX給我們帶來提高用戶體驗、減少HTTP連接數等好處的同時,也漸漸顯露出一些不足之處,比如:

  1. 無法使用瀏覽器的前進、後退來切換前後數據。
  2. 當我們將瀏覽器地址欄中的鏈接與朋友分享時,可能實際上卻並非我們期望的內容。
  3. 單純地使用AJAX不利於搜索引擎優化。

實現無刷新跳轉

上面都是一些理論知識(部分整理於網上),那麼無刷新跳轉要怎麼實現呢?很簡單的一句代碼:

  1. history.pushState(null, ”, ’newpage.html’);

點此查看效果
如果你使用的是HTML5瀏覽器,並點擊了上面的按鈕,那麼應該可以看到,地址欄的地址發生了改變,頁面卻沒有刷新或跳轉。

 

這是一個最簡單的Demo,雖然實現了地址的無刷新跳轉,但內容卻沒有對應改變,我們只要在pushState的同時配合上AJAX,一個無刷新的頁面跳轉效果便完成了,AJAX的實現與本文主題無關,這裏就不再贅述,下面給出的Demo下載會有AJAX部分的代碼。

兼容瀏覽器前進後退效果

簡單地利用history.pushState,雖然可以實現無刷新地址跳轉,但並沒有解決在瀏覽器中前進後退,內容並沒有相應改變這個問題,此時就需要用到window.onpopstate事件了,當頁面地址發生改變時,便會觸發window對象的onpopstate事件,而我們只要在pushState的同時將當前頁面的參數傳遞給瀏覽器,並在onpopstate事件中作出相應便可以了:

  1. history.pushState({title: ’頁面標題’, html: ’頁面HTML’}, ”, ’newpage.html’);
  2. window.onpopstate = function(event){
  3.         if(event && event.state){
  4.                 document.title = event.state.title;
  5.                 document.body.innerHTML = event.state.html;
  6.         }
  7. }

當然,還有許多需要考慮的因素,如當頁面打開時event.state爲空,最後一次後退會失效等等,這就需要在頁面載入時先將當前的標題與HTML保存到變量中,並在當event.state爲空時將變量中的內容顯示出來。

 

還有考慮當鏈接中含有井號“#”時應如何處理等等……

無刷新跳轉的具體實現

熬夜將博文寫出,順便將Demo寫成了一個jQuery插件,精神比較差,基本的功能已經實現,一些細節就暫不考慮了,如果有什麼問題歡迎大家提出。

 

話說這次的博文也寫的比較語無倫次,還請大家見諒。。

下載地址:http://vdisk.weibo.com/s/bR64T

發佈了57 篇原創文章 · 獲贊 6 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章