摘要:單頁應用的原理從早起的根據的變化,到根據的的變化,實現無刷新條件下的頁面重新渲染。那么在單頁應用中是如何監聽的變化呢,本文將總結一下,如何在單頁頁面中優雅的監聽的變化。在下幾章中,重點介紹一下如何監聽的改變。
??單頁應用的原理從早起的根據url的hash變化,到根據H5的history的變化,實現無刷新條件下的頁面重新渲染。那么在單頁應用中是如何監聽url的變化呢,本文將總結一下,如何在單頁頁面中優雅的監聽url的變化。
單頁應用原理
監聽url中的hash變化
監聽通過history來改變url的事件
replaceState和pushState行為的監聽
原文在我的博客中:https://github.com/forthealll...
歡迎star
一、單頁應用原理??單頁應用的原理,在我們的上一篇文章中React-Router源碼閱讀已經講的很詳細,這里做一個簡單介紹。單頁應用使得頁面可以在無刷新的條件下重新渲染,通過hash或者html5 Bom對象中的history可以做到改變url,但是不刷新頁面。
(1)通過hash來實現單頁路由??早期的前端路由是通過hash來實現的:
??改變url的hash值是不會刷新頁面的。
??因此可以通過hash來實現前端路由,從而實現無刷新的效果。hash屬性位于location對象中,在當前頁面中,可以通過:
window.location.hash="edit"
來實現改變當前url的hash值。執行上述的hash賦值后,頁面的url發生改變。
賦值前:http://localhost:3000
賦值后:http://localhost:3000/#edit
在url中多了以#結尾的hash值,但是賦值前后雖然頁面的hash值改變導致頁面完整的url發生了改變,但是頁面是不會刷新的。
此外,除了可以通過window.location.hash來改變當前頁面的hash值外,還可以通過html的a標簽來實現:
edit(2)通過history實現前端路由
??HTML5的History接口,History對象是一個底層接口,不繼承于任何的接口。History接口允許我們操作瀏覽器會話歷史記錄。
History提供了一些屬性和方法。
History的屬性:
History.length: 返回在會話歷史中有多少條記錄,包含了當前會話頁面。此外如果打開一個新的Tab,那么這個length的值為1
History.state:
保存了會出發popState事件的方法,所傳遞過來的屬性對象(后面會在pushState和replaceState方法中詳細的介紹)
History方法:
History.back(): 返回瀏覽器會話歷史中的上一頁,跟瀏覽器的回退按鈕功能相同
History.forward():指向瀏覽器會話歷史中的下一頁,跟瀏覽器的前進按鈕相同
History.go(): 可以跳轉到瀏覽器會話歷史中的指定的某一個記錄頁
History.pushState():pushState可以將給定的數據壓入到瀏覽器會話歷史棧中,該方法接收3個參數,對象,title和一串url。pushState后會改變當前頁面url,但是不會伴隨著刷新
History.replaceState():replaceState將當前的會話頁面的url替換成指定的數據,replaceState后也會改變當前頁面的url,但是也不會刷新頁面。
上面的方法中,pushState和repalce的相同點:
就是都會改變當前頁面顯示的url,但都不會刷新頁面。
不同點:
pushState是壓入瀏覽器的會話歷史棧中,會使得History.length加1,而replaceState是替換當前的這條會話歷史,因此不會增加History.length.
(3)總結??通過改變hash值,或者history的repalceState和pushState都可以實現無刷新的改變url。這樣還留有一個問題需要解決:
??如何監聽url的改變
??因為我們不僅要無刷新的改變url,還要監聽到這個url改變的行為,根據該行為去重新渲染視圖。在下幾章中,重點介紹一下如何監聽url的改變。
二、監聽url中的hash變化??通過hash改變了url,會觸發hashchange事件,只要監聽hashchange事件,就能捕獲到通過hash改變url的行為。
window.onhashchange=function(event){ console.log(event); } //或者 window.addEventListener("hashchange",function(event){ console.log(event); })
當hash值改變時,輸出一個HashChangeEvent。該HashChangeEvent的具體值為:
{isTrusted: true, oldURL: "http://localhost:3000/", newURL: "http://localhost:3000/#teg", type: "hashchange".....}
有了監聽事件,且改變hash頁面不刷新,這樣我們就可以在監聽事件的回調函數中,執行我們展示和隱藏不同UI顯示的功能,從而實現前端路由。
三、監聽通過history來改變url的事件在上一章講到了通過History改變url有以下幾種方法:History.back()、History.forward()、History.go()、History.pushState()和History.replaceState()。
同時在history中還支持一個事件,該事件為popstate。第一想法就是如果popstate能夠監聽所有的history方法所導致的url變化,那么就大功告成了。遺憾的是:
History.back()、History.forward()、History.go()事件是會觸發popstate事件的,但是History.pushState()和History.replaceState()不會觸發popstate事件。
如果是History.back(),History.forward()、History.go()那么會觸發popstate事件,我們只需要:
window.addEventListener("popstate", function(event) { console.log(event); })
就可以監聽到相應的行為,手動調用:
window.history.go(); window.history.back(); window.history.forward();
都會觸發這個事件,此外,在瀏覽器中點擊后退和前進按鈕也會觸發popstate事件,這個事件內容為:
PopStateEvent?{isTrusted: true, state: null, type: "popstate", target: Window, currentTarget: Window,?…}
但是,History.pushState()和History.replaceState()不會觸發popstate事件,舉例來說:
window.addEventListener("popstate", function(event) { console.log(event); }) window.history.pushState({first:"first"}, "page 2", "/first"})
上述例子中不會有任何的輸出,因為并沒有監聽的popstate事件的發生。
但是History.go和History.back()等,雖然可以觸發popstate事件,但是都會刷新頁面,我們在單頁應用中使用的是replaceState和pushState,因此這里還有一個等待解決的問題:
如何監聽replaceState和pushState行為
四、replaceState和pushState行為的監聽??在上面的例子中我們發現History.replaceState和pushState確實不會觸發popstate事件,那么如何監聽這兩個行為呢。可以通過在方法里面主動的去觸發popState事件。另一種就是在方法中創建一個新的全局事件。
具體做法為:
var _wr = function(type) { var orig = history[type]; return function() { var rv = orig.apply(this, arguments); var e = new Event(type); e.arguments = arguments; window.dispatchEvent(e); return rv; }; }; history.pushState = _wr("pushState"); history.replaceState = _wr("replaceState");
這樣就創建了2個全新的事件,事件名為pushState和replaceState,我們就可以在全局監聽:
window.addEventListener("replaceState", function(e) { console.log("THEY DID IT AGAIN! replaceState 111111"); }); window.addEventListener("pushState", function(e) { console.log("THEY DID IT AGAIN! pushState 2222222"); });
這樣就可以監聽到pushState和replaceState行為。
參考文章:https://stackoverflow.com/que...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100525.html
摘要:單頁應用的原理從早起的根據的變化,到根據的的變化,實現無刷新條件下的頁面重新渲染。那么在單頁應用中是如何監聽的變化呢,本文將總結一下,如何在單頁頁面中優雅的監聽的變化。在下幾章中,重點介紹一下如何監聽的改變。 ??單頁應用的原理從早起的根據url的hash變化,到根據H5的history的變化,實現無刷新條件下的頁面重新渲染。那么在單頁應用中是如何監聽url的變化呢,本文將總結一下,...
摘要:單頁應用的原理從早起的根據的變化,到根據的的變化,實現無刷新條件下的頁面重新渲染。那么在單頁應用中是如何監聽的變化呢,本文將總結一下,如何在單頁頁面中優雅的監聽的變化。在下幾章中,重點介紹一下如何監聽的改變。 ??單頁應用的原理從早起的根據url的hash變化,到根據H5的history的變化,實現無刷新條件下的頁面重新渲染。那么在單頁應用中是如何監聽url的變化呢,本文將總結一下,...
摘要:本文的介紹的是如何設計一個通用的可以以較小的侵入性,自動上報前端的性能數據。具體的做法可以看我的上一篇文章在單頁應用中,如何優雅的監聽的變化。三如何上報性能數據那么如何上報性能數據呢,我們第一反應就是通過請求的形式來上報前端性能數據。 ??最近在做一個較為通用的前端性能監控平臺,區別于前端異常監控,前端的性能監控主要需要上報和展示的是前端的性能數據,包括首頁渲染時間、每個頁面的白屏時...
摘要:本文的介紹的是如何設計一個通用的可以以較小的侵入性,自動上報前端的性能數據。具體的做法可以看我的上一篇文章在單頁應用中,如何優雅的監聽的變化。三如何上報性能數據那么如何上報性能數據呢,我們第一反應就是通過請求的形式來上報前端性能數據。 ??最近在做一個較為通用的前端性能監控平臺,區別于前端異常監控,前端的性能監控主要需要上報和展示的是前端的性能數據,包括首頁渲染時間、每個頁面的白屏時...
摘要:本文的介紹的是如何設計一個通用的可以以較小的侵入性,自動上報前端的性能數據。具體的做法可以看我的上一篇文章在單頁應用中,如何優雅的監聽的變化。三如何上報性能數據那么如何上報性能數據呢,我們第一反應就是通過請求的形式來上報前端性能數據。 ??最近在做一個較為通用的前端性能監控平臺,區別于前端異常監控,前端的性能監控主要需要上報和展示的是前端的性能數據,包括首頁渲染時間、每個頁面的白屏時...
閱讀 3487·2023-04-25 20:41
閱讀 2660·2023-04-25 16:40
閱讀 1432·2021-09-23 11:44
閱讀 1252·2021-09-10 10:51
閱讀 1681·2021-09-07 09:59
閱讀 1642·2019-12-27 12:08
閱讀 551·2019-08-30 15:44
閱讀 3334·2019-08-30 11:08