登陸成功後跳轉到上一個頁面是很常見的需求,好比在天貓添加購物車時網站會效驗用戶登陸狀況,若未登陸則跳轉登陸,登陸成功返回到先前的商品頁。javascript
這個功能實現並不困難,但由於個人奇思妙想讓我前後瞭解了window.history
對象以及窗口關閉/離開事件onbeforeunload
,那麼讓這個需求作個引子,讓咱們開始一次有趣的探索之旅。html
不論是從什麼頁面進入的登陸頁,老是得先有個離開頁面的過程,那我在離開前一個頁面時先記住頁面,登陸成功調回來不就行了,因此我第一就想到了onbeforeunload
事件。java
關於onbeforeunload
事件,MDN上說的很詳細,此事件在窗口即將被關閉(關閉瀏覽器 / 跳轉到其它頁面)時會觸發,看個例子:angularjs
window.onbeforeunload = function () { console.log('頁面要離開了。'); };
複製此代碼到瀏覽器控制檯並回車執行,以後不管咱們跳轉或關閉窗口,你會發現console
都會執行。瀏覽器
onbeforeunload
事件的使用場景其實不少,好比博客園博離開未保存的博客編輯窗口,再如信息較多的表單填寫等等,onbeforeunload
主要起防止誤操做丟失頁面的做用,多一次挽回的機會。緩存
值得一提的是onbeforeunload
事件中沒法使用window.open()
以及window.alert()
方法,若你使用,瀏覽器會拋出blocked xxxx during beforeunload
相似的錯誤,意思就是在瀏覽器關閉前禁止使用彈窗或打開新窗口。性能
咱們前面又說經常使用於離開頁面給出友好彈窗提示,不能用alert
怎麼實現呢,得換一種方式,這裏貼出代碼:學習
window.onbeforeunload = function (e) { var e = e || window.event, dialogText = '頁面還未保存,肯定要離開嗎?'; // 兼容IE8和Firefox 4以前的版本 if (e) { e.returnValue = dialogText; }; // Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+ return dialogText; };
當你運行這段代碼並嘗試關閉頁面時,你會看到頁面確實給出了以下提示:網站
但提示文字並無使用咱們本身定義語句,這是由於瀏覽器在以後的版本中已統一提示語句,自定義語句只在低版本瀏覽器適用。url
onbeforeunload
這麼好用,兼容性怎麼樣呢,經過 can i use 一查,兼容性很是出色,完美兼容 IE6。
那麼我有沒有使用onbeforeunload
來處理登陸成功返回上個頁面呢?很遺憾並無,A頁面跳B頁面,B頁面跳C頁面,只要頁面跳轉此事件都會觸發,頁面跳轉自己就屬於高頻操做,性能代價太大。
我忽然靈機一動!!!幹嗎要本身去記錄頁面跳轉呢,window.history
不是已經幫咱們作了這件事嗎,想一想還有點小激動。
打開瀏覽器控制檯,輸入window.history
並回車,能夠看到以下屬性:
由於隱私問題,history對象早已再也不展現用戶瀏覽記錄列表,只保留了go,back,forward
以及HTML5
新增的pushState
與replaceState
方法用於操做頁面記錄。說通俗點,記錄我不給你看,但容許你操做。
新增的兩個方法咱們先不說,這裏主要說說前三個。咱們來作個小實驗,先打開百度,跳轉到嗶哩嗶哩,再跳轉到騰訊視頻。如今打開控制檯,輸入window.history.back()
並回車,你會發現頁面從騰訊視頻跳到了嗶哩嗶哩。按下方向鍵 ↑ 再回車,頁面又回到了最初的百度。
如今輸入window.history.forward()
並回車,頁面又會跳到B站,重複此操做,B站又跳到騰訊視頻。
其實不難理解,假設已經創建了A-B-C
三個節點,使用back
就是今後節點往回退,相反的,forward
就是今後節點往前進。
咱們在騰訊視頻頁面輸入window.history.go(-2)
,你會發現一下回到了百度,由於它等同於執行了2次back
方法。對應的,輸入window.history.go(2
)回車,頁面又能從百度回到騰訊,它等同於執行了2次forward
方法,是否是很簡單。
因而我就想到了這樣的邏輯:
function login() { //do something... //返回上個頁面 window.history.back(); };
因而某位用戶將網站的登陸頁添加到了收藏夾,打開瀏覽器顯示百度首頁,點擊收藏夾跳轉登陸頁,登陸成功後因而網站跳轉百度,用戶一臉懵逼....
很遺憾,history pass,不符合要求。
使用onbeforeunload
每一個頁面都會觸發,性能很差,使用history
咱們是不用記錄了,結果記錄不受網站控制,網站外部也會記。那麼咱們就綜合一下,須要記錄的時候咱們本身記。
一共也就兩個地方須要記憶,咱們知道登陸通常都在頁頭,你想進入登陸頁必須點擊登陸按鈕,那麼這個時候記錄就行了。
第二種狀況就是程序跳轉登陸頁,好比token
過時自動跳轉提示登陸,那麼在程序中須要跳轉的地方也去記錄。
由於登陸屬於全站性的操做,你也不知道用戶在哪一個頁面進入的登陸,因此像我這邊使用angularjs
開發的項目,就在總module
上註冊一個登陸相關的service,這裏只說具體方法實現:
// 在跳轉登陸前調用,用於記錄當前頁面 function localStorgeUrl() { //取當前頁面地址,這裏模擬是百度 // let pathArr = window.location.pathname.split('/'); // let url = pathArr[pathArr.length - 1]; let url = 'http://www.baidu.com'; //本地存儲該頁面 window.localStorage.setItem('url', url); }; function redirectUrl() { //獲取緩存路徑 let url = window.localStorage.getItem('url'); //假設用戶從外網進入登陸頁,取不到的狀況跳轉首頁 url ? location.href = url : location.href = 'index.html'; }; //登陸 function login() { // 登陸相關操做,假設登陸成功 redirectUrl(); }; //跳轉登陸頁前調用 localStorgeUrl(); //開始登陸 login();
這裏只是貼一個思路,若是有緣人看到有更好的作法,也歡迎討論。本文從實現功能登陸成功返回上個頁面爲引子,介紹了頁面關閉事件onbeforeunload與history,也算一次不錯的學習,那麼就寫到這裏。