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,也算一次不错的学习,那么就写到这里。

相关文章
相关标签/搜索