詳解單頁面路由的幾種實現原理(附demo)


前言

路由是每個單頁面網站必須要有的,所以,理解一下原理,我覺得還是比較重要的。

本篇,基本不會貼代碼,只講原理,代碼在頁底會有githup地址,主意,一定要放在服務本地服務器里跑(因為有ajax),

希望能幫到你。

眾所周知單頁面網站的路徑跳轉全是通過js來控制的,下面咱們來講講

第一種:url完全不動型

這一種的情況是url完全不動,即你的頁面怎么改變,怎么跳轉url都不會改變

這種情況的原理 就是純ajax拿到頁面后替換原頁面中的元素,

這種情況沒什么好講的,好的一言不和上代碼    demo(地址在頁底)   這里有全部的代碼

第二種:帶hash(#)型

這種類型的優點就是刷新頁面,頁面也不會丟。

實現原理:

小明說:如果window有一個事件能讓我監聽url的變化,那我就能實先路由,

那樣我就可以根據url的變化,來通過ajax請求參數來渲染頁面,

一個url對應一個頁面,也不會重復,多好了。

我:還真有,但是只能監聽 #后面參數的變化。

小明說:唉,那就湊合一下把。

通過監聽 hash(#)的變化來執行js代碼 從而實現 頁面的改變      

核心代碼:

window.addEventListener('hashchange',function(){
self.urlChange()
})

就是通過這個原理 只要#改變了 就能觸發這個事件,這也是很多單頁面網站的url中都也 (#)的原因

demo在下面

第三種:無hash(#)型

這種類型是通過html5的最新history api來實現的   能正常的回退前進  很好

url是這樣的  www.ff.ff/jjkj/fdfd/fdf/fd       和普通的url一樣,但是也有缺點 ,就是一刷新頁面 頁面就會丟,

因為 只要刷新 這個url(www.ff.ff/jjkj/fdfd/fdf/fd)就會請求服務器,然而服務器上根本沒有這個資源,所以就會報404,解決方案就 配置一下服務器端(可以百度一下)

實現原理:

用了 這幾個 api

history.pushState
history.replaceState
history.state
window.onpopstate事件

第一步:history.pushState(null,null,"/abc");  改變url

第二部:執行一個函數(這個函數里有改變頁面的代碼)

就這末簡單。

 

 

下面講一下這幾個api怎么用

pushState是將指定的URL添加到瀏覽器歷史里,存儲當前歷史記錄點API:history.pushState(state, title, url)

// @state狀態對象:記錄歷史記錄點的額外對象,可以為空
// @title頁面標題:目前所有瀏覽器都不支持
// @url可選的url:瀏覽器不會檢查url是否存在,只改變url,url必須同域,不能跨域

history.pushState的目的

SEO優化
更少的數據請求
更好的用戶體驗

history.replaceState

replaceState是將指定的URL替換當前的URL,替換當前歷史記錄點

replaceState的api和pushState類似,不同之處在於replaceState不會在window.history里新增歷史記錄點,而pushState會在歷史記錄點里新增一個記錄點的

history.state

當前URL下對應的狀態信息。如果當前URL不是通過pushState或者replaceState產生的,那么history.state是null。

state對象雖然可以存儲很多自定義的屬性,但對於不可序列化的對象則不能存儲

window.onpopstate事件

window.onpopstate事件主要是監聽歷史記錄點,也就是說監聽URL的變化,但會忽略URL的hash部分。

history.go和history.back(包括用戶按瀏覽器歷史前進后退按鈕)觸發,並且頁面無刷的時候(由於使用pushState修改了history)會觸發popstate事件,事件發生時瀏覽器會從history中取出URL和對應的state對象替換當前的URL和history.state。通過event.state也可以獲取history.state。

注意點:

javascript腳本執行window.history.pushState和window.history.replaceState不會觸發onpopstate事件。
谷歌瀏覽器和火狐瀏覽器在頁面第一次打開的反應是不同的,谷歌瀏覽器奇怪的是回觸發onpopstate事件,而火狐瀏覽器則不會。

 

最后:

這3個demo 實現的還算可以,代碼結構也還好把,最長的120多行,相信你可以看的懂,如果真的項目中需要用的話,,那那代碼結構還需要優化一下,

本來我還想着把這3個deom給整合一下呢,變成一個功能完備的路由,唉,最近活多啊,下次吧!!!! 

 

好了 是給   完整例子的時候了    demo        

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM