研究区分onbeforeunload事件是刷新还是关闭



研究区分onbeforeunload事件是刷新还是关闭

原创 2015年06月27日 10:26:15

                   

  • 编辑
  • 删除

    一、原因

    最近公司的一个web项目需要在关闭网页窗口的时候对一些资源做处理,必须判断是刷新还是关闭,这很苦逼,造成必须做判断的问题是由miniUI的一个实时编辑grid控件引起的,因为表格控件在编辑,新增记录的时候,触发了reload的事件,UI底层可能做得不好,这些操作都会触发onbeforeunload 事件里的刷新 ,但是由于控件上的耦合性问题,不能不使用miniUI控件,问题只能去解决和规避掉。

    二、分析

    我的系统里能触发onbeforeunload事件的有以下:

     1、F5刷新
     2、Ctrl+R刷新
     3、miniUI表格的增删改
     4、关闭窗口(这个才是真正想要的)
    
        
        
    • 1
    • 2
    • 3
    • 4
    • 5

    这四个行为都会触发onbeforeunload事件,现在我必须获取到第四个动作,也就是关闭窗口。

    查询相关的onbeforeunload浏览器触发:

        关闭浏览器窗口
        通过地址栏或收藏夹前往其他页面的时候
        点击返回,前进,刷新,主页其中一个的时候
        点击 一个前往其他页面的url连接的时候
        调用以下任意一个事件的时候:
         click,document write,document open,document close,window close,window navigate,window NavigateAndFind,location,replace,location reload,form submit 
        当用window open打开一个页面,并把本页的window的名字传给要打开的页面的时候。
        重新赋予location.href的值的时候
        通过input type=”submit”按钮提交一个具有指定action的表单的时候
        可以用在以下元素:BODY, FRAMESET, window
        平台支持:IE4+/Win, Mozilla 1.7a+, Netscape 7.2+, Firefox0.9+
    
        
        
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    其实真正做到判断触发onbeforeunload事件的话是不可能的,因为没有放出相关的接口,做不了判断,网上可能出现过类似下边判断刷新还是关闭的判断方式:

             window.onbeforeunload=function(e){
            //获取事件鼠标的位置
            var n = window.event.screenX - window.screenLeft; 
            //获取浏览器界面可活动的窗口宽度(50是右上角关闭按钮的宽度)
            var b = n > document.documentElement.scrollWidth-50; 
            //window.event.clientY表示事件的y值(鼠标)
            //window.event.altKey表示是否按下列alt键(alt+F4)
            if(b && window.event.clientY < 0 || window.event.altKey) 
            {
                alert("是关闭而非刷新");
                window.event.returnValue ="是否要离开此页面?";   
            }else{
                alert("是刷新而非关闭");
            }
        }
        
        
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    从以上代码看,远远不能满足我系统里边出现的情况,miniUI增删改都会触发,Ctrl+R也会触发刷新,还有一个特别大的漏洞是,当你鼠标放在关闭按钮上的时候,同时按下F5刷新页面,代码会误认为是关闭。

    最后本人解决的方法是,系统里边禁止掉刷新,用户不能通过键盘刷新页面

      $(document).keydown(function () {
                if ((event.keyCode == 116) || //屏蔽 F5 刷新键
                    (event.ctrlKey && event.keyCode == 82)) { //Ctrl + R
                    event.keyCode = 0;
                    event.returnValue = false;
                }
            });
        
        
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    然后使用此段代码:

     window.onbeforeunload=function(e){
        //window.event.clientY < 0表示鼠标已经离开了document的区域
       if(window.event.clientY < 0 || window.event.altKey) 
            {
                alert("是关闭而非刷新");
                window.event.returnValue ="您是否要离开此页面?";   
            }else{
                alert("是刷新而非关闭");
            }
        }
        
        
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    window.event.clientY < 0表示鼠标已经离开了document的区域,如图:
    红色区域,就是window.event.clientY < 0的情况,蓝色的是>=0

    这里写图片描述

    由于我禁用了键盘的刷新,目前只能通过鼠标操作刷新,鼠标点击刷新或者连接其他关闭窗口时,这时候window.event.clientY < 0,此时就认为是离开本窗口页面,就认为是关闭了。(和上边说的一样,我的任务仅是规避掉miniUI表格增删改触发onbeforeunload事件的情况,此处的刷新我认为是关闭,因为已经重新刷新系统里,就相当于重新打开页面一个道理。

    以上的情况对我是完美了,其实我的系统窗口是通过window.open弹窗出来的,弹窗出来不会有任何刷新按钮,在IE下可以做到没有地址栏和其他状态栏,谷歌下仅有地址栏,但是地址栏是不可编辑的,也没有刷新按钮,所以,问题就解决了。

    这里写图片描述

    接下来是关闭时做的代码操作:

        var bCloseFlag=false;//关闭窗口标志位
        window.onbeforeunload=function(e){
            //一下是判断onbeforeunload是关闭还是刷新的情况
            var n = window.event.screenX - window.screenLeft; 
            if(window.event.clientY < 0 || window.event.altKey) 
            {
                // alert("是关闭而非刷新");
                window.event.returnValue ="是否离开页面?";
                bCloseFlag=true;
    
            }else{
                // alert("是刷新而非关闭");
            }
        }
        //关闭浏览器的时候释放资源
        window.onunload = function() {
            if (bCloseFlag) {
                 try{
                    if(window.alarmConfirmChildWin){
                        window.alarmConfirmChildWin.close();
                    }
                    if(window.showPicChildWin){
                        window.showPicChildWin.close();
                    }
                    //释放所有的资源
                    //**此处做相关的关闭窗口后的代码**
                }catch(e){}finally{}
            }
        }
        
        
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    三、结论

    区分onbeforeunload事件是刷新还是关闭实际上是不可能的,要做到如上我的情况,如要满足三个:
    1、系统窗口使用window.open弹窗出来,禁止了所有的按钮和状态栏和地址栏等(刷新按钮,主页按钮等都不会显示),这种情况估计很多系统不会用;
    2、代码禁止一切用户刷新操作,比如Ctrl+RF5
    3、使用代码即可判断if(window.event.clientY < 0 || window.event.altKey)是关闭的情况

    版权声明:本文为博主原创文章,未经博主允许不得转载。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值