摘要:最后通過這些自己實現(xiàn)小型的路由。對象還提供方法這個方法用以監(jiān)聽瀏覽器在不同歷史記錄中進行切換,而觸發(fā)相應(yīng)的事件。這時調(diào)用方法后頁面回退,同時頁面發(fā)生刷新這時無法監(jiān)聽這個事件。所以可以進行降級使用來進行路由設(shè)計。不過,還提供了一個。
這篇文章主要是記錄下HTML5中history提供的pushState, replaceStateAPI。最后通過這些API自己實現(xiàn)小型的路由。
關(guān)于window.history提供的API請參見Mozilla文檔
其中history提供的pushState和replaceState2個API提供了操作瀏覽器歷史棧的方法。
其中pushState:
history.pushState(data, null, "#/page=1"); pushState接收3個參數(shù),第一個參數(shù)為一個obj,表示瀏覽器 第二個參數(shù)是document.title的值,一般設(shè)定為`null` 第三個參數(shù)string,用以改變 當(dāng)前url
pushState方法在改變url的同時向瀏覽器歷史棧中壓入新的歷史記錄。
接收url的參數(shù)為string類型,用以改變當(dāng)前地址欄的url.需要注意的一點就是這個參數(shù)不能和跨域,即協(xié)議,域名,端口必須都是相同的,如果出現(xiàn)跨域的情況,即會提示:
Uncaught DOMException: Failed to execute "pushState" on "History": A history state object with URL "http://www.baidu.com/" cannot be created in a document with origin "http://commanderXL.com" and URL
Example:
打開www.baidu.com history.pushState(null, null, "?page=1") //地址欄變成 www.baidu.com/?page=1 history.pushState(null, null, "#page=2"); //地址欄變成 www.baidu.com/#page=2
其中replaceState:
history.replaceState(null, null, "#page=2");
replaceState接收的參數(shù)pushState相同,但是最終的效果是:地址欄url會根據(jù)接收的參數(shù)而變化,但是瀏覽器并未在當(dāng)瀏覽歷史棧中增加瀏覽器的歷史記錄,而是替換當(dāng)前的瀏覽器歷史記錄。
通過pushState和replaceState雖然能改變URL,但是不會主動觸發(fā)瀏覽器reload。
window對象還提供popstate方法:
window.addEventListener("popstate", function() { });
這個方法用以監(jiān)聽瀏覽器在不同歷史記錄中進行切換,而觸發(fā)相應(yīng)的事件。
在瀏覽器提供的history對象上還有go, back方法,用以模擬用戶點擊瀏覽器的前進后退按鈕。在某個web應(yīng)用當(dāng)中,比如點擊了標(biāo)簽,發(fā)生了頁面的跳轉(zhuǎn)。這時調(diào)用history.back();方法后頁面回退,同時頁面發(fā)生刷新,這時window.onpopstate無法監(jiān)聽這個事件。但是如果是通過pushState或者replaceState來改變URL且不發(fā)生瀏覽器刷新的話,再使用history.back()或history.go(),這樣popstate事件會被觸發(fā)。
history.pushState({page: 1}, null, "?page=1"); history.pushState({page: 2}, null, "?page=2"); history.back(); //瀏覽器后退 window.addEventListener("popstate", function(e) { //在popstate事件觸發(fā)后,事件對象event保存了當(dāng)前瀏覽器歷史記錄的狀態(tài). //e.state保存了pushState添加的state的引用 console.log(e.state); //輸出 {page: 1} });
PS: 通過pushState在url上添加?page=1可以通過location.search去獲取search的內(nèi)容。不過如果通過location.search去改變url的話是會主動觸發(fā)瀏覽器reload的。這個特性可以和下面將的關(guān)于hash的內(nèi)容對比下。
API大致了解了,那么這些方法可以運用到哪些地方呢?一個比較常用的場景是就在單頁應(yīng)用中,通過這些API完成前端的路由設(shè)計,利用pushState, replaceState可以改變url同時瀏覽器不刷新,并且通過popstate監(jiān)聽瀏覽器歷史記錄的方式,完成一系列的異步動作。
//路由 const Router = []; const addRoute = (path = "", handle = () => {}) => { let obj = { path, handle } Router.push(obj); } //添加路由定義 addRoute("/post", function() { //do something }); addRoute("/login", function() { //do something }) //路由處理 const routeHandle = (path) => { Router.forEach((item, index) => { if(item.path === path) { item.handle.apply(null, [path]); return true; } }) return false; } //攔截默認(rèn)的a標(biāo)簽行為 document.addEventListener("click", function(e) { let dataset = e.target.dataset; if(dataset) { if(routeHandle(dataset.href)) { //阻止默認(rèn)行為 e.preventDefault(); } } })
大致的實現(xiàn)思路就是,通過添加路由信息,然后攔截標(biāo)簽的默認(rèn)行為,并與注冊的路由信息進行匹配。若匹配成功調(diào)用對應(yīng)的handle方法.
不過pushState和replaceState方法在低版本的IE瀏覽器下兼容性不是很好。所以可以進行降級使用hash來進行路由設(shè)計。
hash?請戳我。
可以通過location.hash獲取url上第一個#(fragment)及后面的內(nèi)容。同時還能通過location.hash改寫其內(nèi)容,且不會主動觸發(fā)瀏覽器reload。 有些功能是不是和pushState和replaceState一樣? 所以為了兼容到低版本的瀏覽器,可以通過監(jiān)聽#變化來進行路由設(shè)計。
那么如何去監(jiān)聽呢? 比較粗暴的一種方式就是polling。
var oldHash = location.hash; setTimeInterval(function() { if(oldHash !== location.hash) { //do something oldHash = location.hash; } }, 100);
不過,H5還提供了一個API: hashchange。它的就可以直接代替上面的polling方法,來監(jiān)聽#的變化。
window.addEventListener("hashchange", function() { routeHandle(locaiton.hash); });
這個小型的路由設(shè)計可以參見我的github.
稍微總結(jié)下:
上面主要介紹了history提供的一些API,hash的相關(guān)知識。在平時可以運用到SPA當(dāng)中,Gmail就是通過hash來進行路由設(shè)計的。它相對于頁面跳轉(zhuǎn)來說:
頁面只需要加載一次。后面的頁面切換可以通過ajax去請求數(shù)據(jù)。頁面體驗更加流暢;
可以利用本地緩存,優(yōu)化頁面體驗。在不同頁面切換的過程中更加流暢;
可進行按需加載...
等等一些實用的好處吧。
項目地址項目地址請戳我
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/80680.html
摘要:原因在于將狀態(tài)對象保存在用戶的磁盤上,以便在用戶重啟瀏覽器時使用,我們規(guī)定了狀態(tài)對象在序列化表示后有的大小限制。新不必須為絕對路徑。新必須與當(dāng)前同源,否則會拋出一個異常。注意絕對不會觸發(fā)事件,即使新的與舊的僅哈希不同也是如此。 Hash hash 屬性是一個可讀可寫的字符串,該字符串是 URL 的錨部分(從 # 號開始的部分),在頁面中的hash有多種功能意義: 錨點 url: htt...
摘要:前端路由庫的作用是改變地址欄,支持瀏覽器前進后退,并同步路由對應(yīng)的視圖,這里以及其依賴的庫說一下路由機制原文地址前提首先簡單介紹一下前端路由機制所依賴的事件及對應(yīng)的事件對于支持新增方法的瀏覽器,可以通過設(shè)置來在瀏覽器棧中新增一條記錄設(shè)置時 前端路由庫的作用是改變地址欄,支持瀏覽器前進、后退,并同步路由對應(yīng)的視圖,這里以react-router及其依賴的history庫說一下路由機制 原...
摘要:部分比較重要部分比較重要重點是下面的,這里操作我們借助實現(xiàn)的邏輯不難,但是利用總是沒有所謂前端路由的那種味,必然也不是主流方法。而現(xiàn)在的前端路由也是基于這個原理實現(xiàn)的。和異曲同工,而且前者可以在該事件之外任何地方隨時使用。 SPA 前端路由原理與實現(xiàn)方式 通常 SPA 中前端路由有2中實現(xiàn)方式,本文會簡單快速總結(jié)這兩種方法及其實現(xiàn): 修改 url 中 Hash 利用 H5 中的 hi...
摘要:部分比較重要部分比較重要重點是下面的,這里操作我們借助實現(xiàn)的邏輯不難,但是利用總是沒有所謂前端路由的那種味,必然也不是主流方法。而現(xiàn)在的前端路由也是基于這個原理實現(xiàn)的。和異曲同工,而且前者可以在該事件之外任何地方隨時使用。 SPA 前端路由原理與實現(xiàn)方式 通常 SPA 中前端路由有2中實現(xiàn)方式,本文會簡單快速總結(jié)這兩種方法及其實現(xiàn): 修改 url 中 Hash 利用 H5 中的 hi...
摘要:目前前端三杰都推介單頁面應(yīng)用開發(fā)模式,在路由切換時替換中最小修改的部分,來減少原先因為多頁應(yīng)用的頁面跳轉(zhuǎn)帶來的巨量性能損耗。 showImg(https://segmentfault.com/img/bVbn1ZN?w=3069&h=2048); 目前前端三杰 Angular、React、Vue 都推介單頁面應(yīng)用 SPA 開發(fā)模式,在路由切換時替換 DOM Tree 中最小修改的部分 ...
閱讀 1879·2019-08-30 15:53
閱讀 3204·2019-08-30 15:44
閱讀 2813·2019-08-26 13:31
閱讀 1957·2019-08-26 12:10
閱讀 802·2019-08-26 11:01
閱讀 2133·2019-08-23 15:32
閱讀 1590·2019-08-23 13:43
閱讀 2545·2019-08-23 11:58