詳解H5中的history單頁面,手動實現單頁面開發,細說h5單頁面原理

就目前來看,前端的單頁面開發佔了很大一部分,一方面無刷新的切換加強了體驗,而且瀏覽器記錄依然存在,前進後退都沒問題,在以前咱們通地址欄中的hash改變來觸發onhashchange方法來實現單頁面應用,可是#的形式老是使人不爽,幸虧h5新增了history.pushState與history.replaceState。javascript

1.介紹APIhtml

history.pushState(data, title [, url]):前端

往歷史記錄堆棧頂部添加一條記錄; data會在onpopstate事件觸發時做爲參數傳遞過去,title爲頁面標題,當前全部瀏覽器都會 忽略此參數(咱們在本身實現的時候能夠隨便填寫),url爲頁面地址,就是若是history.pushState({name:'home'},'home page' ,'home')則地址欄就成了/home,更神奇的是此時不會向後端發送請求,僅僅是url改變。vue

history.replaceState(data, title [, url]) :java

更改當前的歷史記錄,參數跟history.pushState(data, title [, url])一致,只不過不會像瀏覽器歷史棧添加數據,而是替代以前的歷史記錄; node

history.state:用於存儲以上方法的data數據,git

window.onpopstate:響應pushState或replaceState的調用;github

 

2.介紹實現單頁面原理ajax

經過以上幾個方法咱們徹底能夠改變url而且監聽到url的變化,好比url由localhost:8000改變成localhost:8000/home,此時咱們經過onpopstate監聽到了這個變化,而且拿到data數據,假設拿到了name,此時假設有如下對應路由表,其實能夠隨便定義,express

let route = {
    home:{
        name:'home',
        url:'./home.html',
        des:'home page'
    },
     class:{
         name:'class',
         url:'./class.html',
         des:'class page'
      }
}

  那咱們就知道此時home對應應該是./home.html,因而咱們利用ajax將./home.html加載過來,此時咱們拿到了home.html的全部信息,因而跟vue或者其餘框架同樣掛載到當前頁面的一個元素上。

注意點:

咱們主動 利用history.pushState({name:'home'},'home page' ,'home')時候並不會觸發onpopstate,就是說此時是沒法知道url變更了,爲了讓頁面順利跳轉又觸發咱們提供的ajax,那麼咱們就要修改一下history.pushState

var pushState = history.pushState;   // 存儲原生 replaceState
history.pushState = function(state, param) {     // 改寫 replaceState
        var urlName = arguments[2];
        var url = route[urlName].url;
        ajax(url)
        return pushState.apply(history, arguments);    // 調用原生的 replaceState
 };

  如上,咱們不只在使用 history.pushState時候,觸發咱們本身定義的ajax函數,加載了頁面,又調用了原生的方法,是不會影響原生歷史記錄和跳轉等問題。

如今咱們知道咱們每次調用history.pushState都會觸發ajax函數

<div id="app"></div>

    <script>
        function ajax(url){
            //步驟一:建立異步對象
            var ajax = new XMLHttpRequest();
            //步驟二:設置請求的url參數,參數一是請求的類型,參數二是請求的url,能夠帶參數,動態的傳遞參數starName到服務端
            ajax.open('get',url);
            //步驟三:發送請求
            ajax.send();
            //步驟四:註冊事件 onreadystatechange 狀態改變就會調用
            ajax.onreadystatechange = function () {
                if (ajax.readyState==4 &&ajax.status==200) {
                    //步驟五 若是可以進到這個判斷 說明 數據 完美的回來了,而且請求的頁面是存在的
                 //輸入相應的內容
                    document.querySelector('#app').innerHTML = ajax.responseText
              }
            }
        }
    <script>

  利用這個ajax就能夠將別的頁面的內容加載到本頁面的#app這個元素上,實現了單頁面跳轉。

3.須要注意的地方和坑:

1.在嘗試該方法前,須要其啓動服務器代理html文件,即靜態的html文件打開會報錯

2.咱們在經過history.pushState改變url瀏覽器並不會跟處理普通url同樣新發送請求,可是咱們在刷新的時候瀏覽器仍是會發送請求,即localhost:8000/home刷新瀏覽器就會請求這個接口,就會致使後臺根本沒有這個路由返回404,(這也是vue-route常常會出現刷新404問題的緣由)解決辦法就是遇到404的都代理給index.html,我測試使用express來起服務的,有一個插件叫 connect-history-api-fallback,使用以後就不會出現這個問題

若是有想要本身嘗試的,這裏附上咱們demo:https://github.com/jiangzhenfei/h5History,下載還只要執行node server.js便可,打開瀏覽器就能夠嘗試了。

相關文章
相關標籤/搜索