使用 HTML5 History 新特性增強 Ajax 的體驗(轉)

來源:互聯網
上載者:User

標籤:http   io   os   使用   ar   sp   資料   div   2014   

一. 情境再現

如大家熟知,Ajax 可以實現頁面的無重新整理操作,但會造成兩個與普通頁面操作(有重新整理地改變頁面)有著明顯差別的問題—— URL 沒有修改以及無法使用前進、後退按鈕。例如常見的 Ajax 分頁,在第一頁點擊第二頁的連結,Ajax 分頁完成後瀏覽器地址欄上顯示的 URL 依然是第一頁的 URL,使用後退按鈕也無法回到第一頁。url 的改變代表一個標識,在傳統的網頁體驗中,內容的變更伴隨 url 的改變,url 的改變、前進和後退按鈕三者之間更加形成一種獨特的導航體驗,而 Ajax 破壞了這種體驗難免會對使用者造成不便。

當然,很早之前,機智的前端工程師們已經想好瞭解決辦法,最為常見的,就是使用 hash ——在 URL 結尾添加形如"#xxx" 的標識,然後用 onhashchange 等方式監聽 hash 值變化作出相應處理。

很麻煩?是的,因此,HTML5 History 中新增了幾個可以優雅地解決這些問題的特性!

二. HTML5 History 的新特性

History 對象從 HTML4 開始引入,HTML5 中增加了 pushState, replaceState 兩個方法,和 popstate 事件。下面作一些簡單的介紹。

1. pushState()方法

pushState() 的作用是往記錄的堆棧中壓入一條記錄,該方法有三個參數:

state object —— 一個對象,用於儲存狀態資訊,當 popstate 事件被觸發時,popstate 事件對象的 state 屬性會包含相應的 state object 的拷貝。state object 的容量很小(Firefox 中強製為 640k),如果需要儲存較大的資料,建議使用 localStorage 或 sessionStorage。

title —— 即被壓入的記錄的頁面的標題,該屬性暫時被所有瀏覽器忽略,實際開發時可以填Null 字元或一個簡短的標題。

url —— 新的記錄的地址,可以是相對路徑或絕對路徑,若為相對路徑則以當前 url 為基址。

2. replaceState()方法

replaceState() 方法與 pushState() 方法類似,參數與 pushState() 也相同,但 replaceState() 方法會修改當前的記錄而並非建立新的記錄,因此在需要更新當前記錄的 state object 或 URL 時,使用該方法會更加合適。

3. popstate 事件

popstate 事件會在啟用的記錄發生變化(如前進、後退、調用 pushState 或 replaceState 方法)時觸發在 window 對象上。如上面所描述,如果被啟用的記錄由 pushState 建立或是被 replaceState 修改,則 popstate 事件的狀態屬性將包含相應的 state object 的拷貝,開發人員可以在 popstate 的回調中調用這些之前儲存在 state object 中的資訊。

值得注意的是,Chrome 會在開啟頁面(包括第一次開啟頁面)以及頁面重新整理時產生 popstate 事件而 Firefox 則不會,這會為開發帶來一些麻煩,但下面會給出解決方案。

4. 瀏覽器安全色
特性 Chrome Firefox (Gecko) Internet Explorer Opera Safari
pushState, replaceState 5 4.0 (2.0) 10 11.50 5.0
history.state 18 4.0 (2.0) 10 11.50 6.0
三. 使用 History 的新特性增強 Ajax 體驗

這裡說的增強體驗,實質就是要解決文章開頭提到的兩個問題 —— Ajax 翻頁時不會修改 URL 以及前進、後退功能無效。

看了上面的方法,相信大家已經能想到基本的解決思路,無非就是在 Ajax 需求產生時 pushState 一條記錄到記錄中,然後在 popstate 的回呼函數中作出相應的處理。當然,要想實際獲得比較好的體驗,要做的內容還是比較複雜的。下面以 Ajax 分頁為例,提供一個完整思路:

  • 每次使用 Ajax 擷取新頁面後,使用 pushState() 把新頁面的 url 壓入記錄棧頂。
  • 監聽 popstate 事件,當使用者前進或後退時在回調中根據前進或後退後的 URL 重新使用 Ajax 擷取頁面內容,實現 Ajax 前進與後退。
  • Chrome 在開啟頁面以及重新整理頁面後會產生 popstate 事件,導致多餘的 Ajax 請求,因此需要 popstate 中利用 url 作為判斷使用者是否在點擊前進或後退功能,抑或是開啟、重新整理頁面,若為前進或後退才觸發 Ajax 擷取相應內容。

基本代碼

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 // 定義 Ajax 擷取分頁方法,這裡不列出具體內容function turnPage(url){    // ...} // 定義 popstate 的回調if( history.pushState ){ // 判斷瀏覽器是否支援 pushState     // currentState 用於記錄 popstate 產生前的頁面 url,頁面載入時初始化 currentState 為當前連結    var currentState = window.location.href;     window.addEventListener(‘popstate‘, function(event){                 // _currentUrl 用於記錄 popstate 產生時的頁面 url        var _currentUrl = window.location.href;                 /* 判斷 currentState 和 _currentUrl 是否相同,         * 若相同則表明這個 popstate 產生前後頁面 url 沒有變化,         * 即頁面是第一次載入頁面或者被重新整理,無需觸發新的 Ajax 請求,         * 若不同則表明 url 已改變,這是觸發 Ajax 擷取內容         */        if( currentState != _currentUrl ){                     console.log(‘擷取新分頁‘);                             turnPage(_currentUrl); // 根據當前 url 重新擷取分頁內容                         currentState = _currentUrl; // 更新 currentState                 }       }); } // 綁定點擊分頁產生 Ajax 請求// 點擊分頁連結,擷取 url 為 currentLink,產生一次 Ajax 請求turnPage(currentLink); // 調用 pushState() 壓入新記錄if( history.pushState ){ // 判斷瀏覽器是否支援 pushState     // 往記錄中壓入新記錄,瀏覽器的地址欄上的 url 同時會被修改為新 url    history.pushState(null, document.title, currentLink);             currentState = window.location.href; // 分頁時更新 currentState 為當前 url}

本站已經根據上面的思路進行了 Ajax 分頁的增強,具體的情況如下:

開啟頁面,url 顯示為首頁的 url

點擊第二頁連結,觸發 Ajax 分頁,在 Ajax 中調用 pushState() ,可以看到,url 已經被修改為第二頁的 url

點擊後退按鈕,url 地址變為第一頁,再在 popstate 的回調中觸發 Ajax 擷取第一頁的內容。

這樣,就做到了既吸收了局部重新整理頁面的好處同時保留傳統的 url 導航體驗。而對於不支援 pushState 的瀏覽器,可以使用漸進增強設計忽略這些瀏覽器,畢竟這是一個增強體驗的功能;當然如果必須照顧那些瀏覽器,也可以採用 hash 的方案代替。

四. 現有的解決方案

如果需要直接的解決方案,可以參考這個封裝好並且實現了跨瀏覽器安全色的庫 —— History.js

本文由 Kayo Lee 發表,本文連結:http://kayosite.com/html5-history-improve-ajax.html

使用 HTML5 History 新特性增強 Ajax 的體驗(轉)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.