關於單頁應用
單頁Web應用(single page web application,SPA),就是隻有一張Web頁面的應用,是加載單個HTML 頁面並在用戶與應用程序交互時動態更新該頁面的Web應用程序。簡單來講就是用戶只須要加載一次頁面就能夠再也不請求,當點擊其餘子頁面時只會有相應的URL改變而不會從新加載。html
單頁應用的實現
若是你的項目涉及到單頁面的話,路由是必不可少的。從上面的介紹中能夠知道單頁應用的實現依賴與路由,在這裏咱們能夠將上面路由的過程分爲兩部分:html5
- 更新URL頁面不刷新
ps: 以前面試被問到過這個問題,如今才恍然大悟面試官大大想要問的是這個點。 ==。
- 監聽URL的變化,執行頁面替換邏輯
實現改變URL頁面不刷新
按照常規的邏輯咱們切換URL好像就會跳轉網頁,可是轉念一項錨連接的URL不是也改變了嗎? 這裏,存在兩種知足需求的方式。web
- 利用URL中的hash方式
瞭解http協議就會知道,url的組成部分有不少,譬如協議、主機名、資源路徑、查詢字段等等,其中包含一個稱之爲片斷的部分,以「#」爲標識。打開控制檯,輸入 location.hash,你能夠獲得當前url的hash部分(若是當前url不存在hash則返回空字符串)。接下來,輸入 location.hash = '123',會發現瀏覽器地址欄的url變了,末尾增長了’#123’字段,而且,頁面沒有被從新刷新。很顯然,這很符合咱們的要求。
- 利用H5的history API
html5引入了一個history對象,包含了一套訪問瀏覽器歷史的api,能夠經過window.history訪問到它。 HTML5 History API包括2個方法:history.pushState()和history.replaceState(),和1個事件:window.onpopstate。這兩個方法都是對瀏覽器的歷史棧進行操做,將傳遞的url和相關數據壓棧,並將瀏覽器地址欄的url替換成傳入的url且不刷新頁面,並且他們的參數也相同,第一個參數用於存儲該url對應的狀態對象,該對象可在onpopstate事件中獲取,也可在history對象中獲取。第二個參數是標題,目前瀏覽器並未實現。第三個參數則是設定的url。通常設置爲相對路徑,若是設置爲絕對路徑時須要保證同源。。不一樣的是pushState 將指定的url直接壓入歷史記錄棧頂,而 replaceState 是將當前歷史記錄棧頂替換成傳入的數據。不太低版本對history AIP的兼容性不是很好。
監聽URL的變化,執行頁面替換邏輯
- 對於hash方式,咱們一般採用監聽hashchange事件,在事件回調中處理相應的頁面視圖展現等邏輯。在不支持hashchange事件的瀏覽器中,咱們只能經過setInterval設置來模擬hashchange(不停的對比URL若是有改變)。
var oldHash = location.hash; var oldURL = location.href; setInterval (function () { var newHash = location.hash; var newURL = location.herf; if (newHash !== oldHash && typeof window.onhashchange === 'function') { // 這裏執行onhashchange的回調 } }, 100)
- 採用history API的形式時,須要觸發onpopstate,popstate 事件只會在瀏覽器某些行爲下觸發, 好比點擊後退按鈕(或者在JavaScript中調用 history.back() 方法)。這也就是說,咱們在使用history API改變瀏覽器的url時,仍須要額外的步驟去觸發 popstate 事件,例如調用 history.back() 會 history.forward() 等方法
兩種實現的比較
總的來講,基於Hash的路由,兼容性更好;基於History API的路由,更加直觀和正式。可是,有一點很大的區別是,基於Hash的路由不須要對服務器作改動,基於History API的路由須要對服務器作一些改造。面試