JS 頁面離開事件 頁面關閉事件,實現登陸成功返回上個頁面

壹 ❀ 引

登陸成功後跳轉到上一個頁面是很常見的需求,好比在天貓添加購物車時網站會效驗用戶登陸狀況,若未登陸則跳轉登陸,登陸成功返回到先前的商品頁。javascript

這個功能實現並不困難,但由於個人奇思妙想讓我前後瞭解了window.history對象以及窗口關閉/離開事件onbeforeunload,那麼讓這個需求作個引子,讓咱們開始一次有趣的探索之旅。html

貳 ❀ 有趣的onbeforeunload

不論是從什麼頁面進入的登陸頁,老是得先有個離開頁面的過程,那我在離開前一個頁面時先記住頁面,登陸成功調回來不就行了,因此我第一就想到了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頁面,只要頁面跳轉此事件都會觸發,頁面跳轉自己就屬於高頻操做,性能代價太大。

叄 ❀ 歷史的掌控者history

我忽然靈機一動!!!幹嗎要本身去記錄頁面跳轉呢,window.history不是已經幫咱們作了這件事嗎,想一想還有點小激動。

打開瀏覽器控制檯,輸入window.history並回車,能夠看到以下屬性:

由於隱私問題,history對象早已再也不展現用戶瀏覽記錄列表,只保留了go,back,forward以及HTML5新增的pushStatereplaceState方法用於操做頁面記錄。說通俗點,記錄我不給你看,但容許你操做。

新增的兩個方法咱們先不說,這裏主要說說前三個。咱們來作個小實驗,先打開百度,跳轉到嗶哩嗶哩,再跳轉到騰訊視頻。如今打開控制檯,輸入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,也算一次不錯的學習,那麼就寫到這裏。

相關文章
相關標籤/搜索