一個網站是由許許多多頁面組成的,超連接將這些頁面鏈接起來,給了用戶一個完整的使用體驗。用戶經過超連接打開一個頁面時,瀏覽器會回收當前頁面而後再渲染新頁面。有時候咱們並不但願是這樣,好比對於一個音樂網站,咱們不但願用戶在切換頁面時中斷當前歌曲的播放。這就須要作到頁面的刷新是局部而不是所有。目前大概有兩種方法能夠實現這種功能。一是將整個網站作成只有一個頁面,模塊切換徹底靠客戶端的js實現;二是經過嵌套iframe的方式實現。iframe方式雖然傳統,可是和單頁面應用相比也有許多優點。好比:內存通常不會泄漏,seo很方便等。本文將主要介紹iframe的實現方式。瀏覽器
如上圖,在最外層的頁面嵌套一個iframe,經過改變iframe的src值來實現頁面的切換。咱們能夠將站內全部連接的target值設爲iframe。因爲iframe是一個獨立的瀏覽器窗口,其切換並不會刷新其外層的容器,這樣就實現了頁面局部刷新的效果。效果是達到了,不過還存在一個問題,那就是頁面的URL不能體如今瀏覽器的地址欄裏,這樣的用戶體驗是很是差的。瀏覽器的地址欄表示的是最外層頁面的地址,若是改變這個地址就會形成整個頁面的刷新。不過好在瀏覽器爲URL增長了hash部分。hash並非http協議的內容,只是在客戶端使用的,hash的改變不會刷新頁面。因此在外層,能夠用hash來體現iframe頁面的地址。好比iframe的地址爲http://a.b.com/user?id=123 ,那麼轉換到瀏覽器地址欄多是http://a.b.com/#/user?id=123。 經過簡單的改動就能實現此功能。函數
上面的流程圖反映了一次頁面跳轉的過程。在iframe中,須要實現一個全局的點擊事件代理,將全部連接的點擊事件攔截下來。攔截後,將連接href值轉換成hash地址,並修改外層src值。外層src值改變後,會觸發hashchange事件,在該事件處理函數中將hash地址再次轉換成頁面真實地址並刷新iframe。這裏有個細節須要注意,刷新iframe時,不能直接設置src值或者location.href的值,由於這會使得iframe也相應產生一條歷史記錄,這回致使瀏覽器的前進後退須要點兩次才生效。經過調用location.replace()方法能夠避免iframe產生歷史記錄。不過該方法在ie10+瀏覽器下有個嚴重的bug。使用瀏覽器的前進和後退鍵時會致使全部頁面的刷新,這就破壞了局部刷新的需求了。這應該是瀏覽器實現上的一個bug,沒有辦法直接解決,不過能夠用其餘方法繞過去。避免iframe產生歷史記錄的方法還有一種,就是在刷新iframe時,先要將原來的iframe節點刪除,而後建立一個新的iframe節點,並將其src設爲對應地址。此時iframe的刷新就不會產生多餘的歷史記錄了。網站
能夠看到內嵌iframe的方式實現是比較簡單的,關鍵的一點就是要把瀏覽器的歷史記錄問題處理好。但願本文提供的信息能有所幫助。spa