easyui修复浏览器刷新后,tab页全部关闭的问题

一.问题描述

  使用easyui搭建的上左右页面布局,当我们在右侧打开了tab页,发现点击浏览器的刷新按钮后,整个页面会被重新渲染,导致所有打开的tab页都被关闭,回到初始状态的问题。

  这个问题虽然不影响业务,但对用户操作造成了一定的困扰。因为浏览器刷新后,tab页全部被关闭,那么用户又需要打开刚才正在使用的tab页,甚至有可能,用户会忘记打开过哪些tab页。

二.解决思路

  因为浏览器刷新后,页面重新渲染,所有tab页都不存在了,其实并不是关闭了tab,只是页面回到了初始状态。所以要解决这个问题,我们可以使用一个变量来保存已经打开的tab页的信息,这样即使页面刷新,我们也可以通过这个变量来恢复到原来的状态。

三.解决步骤

  1.使用cookie来保存这个变量

   //从cookie中读取treeNodes的值,其中保存着处于打开状态的tab页的信息
    treeNodes = $.cookie("treeNodes");
    if(treeNodes == null){
        //如果为空,则表示没有打开的tab页
        treeNodes = [];
    }else{
        //如果不为空,则表示加载这个页面之前,存在已经打开的tab页
        //注意:cookie中存放的是string类型,需要转化为json数组对象
        treeNodes = $.parseJSON(treeNodes);
    }

   2.为菜单树添加onLoadSuccess事件,用来恢复原来已经打开的tab页的状态;菜单树的onClick事件中,每次打开一个tab,增加一个对应的值

    /*
     * 获取左侧菜单树,并为其节点指定单击事件
     */
    $("#home-west-tree").tree({
        url: "${ctx }/tree.do",
        method: "get",
        animate: true,
        //当tree加载成功后,检查是否之前存在已经打开的tab页
        //如果存在,则打开对应的tab页
        onLoadSuccess: function(){
            for(var i = 0; i<treeNodes.length; i++){
                var treeNode = treeNodes[i];
                //通过节点的id来找到node
                var node = $("#home-west-tree").tree("find",treeNode.id);
                addTab({
                    url: "${ctx }/" + node.attributes.url,
                    title: node.text
                });
            }
        },
        onClick: function(node){
            if(node.attributes && node.attributes.url){
                addTab({
                    url: "${ctx }/" + node.attributes.url,
                    title: node.text
                });
                //当用户点击tree打开tab页时记录到treeNodes中
                //因为tree和tabs相关的属性就只有text和title,所以必须保存这一个属性,
                //后来发现tree只有一个find方法(通过id查找node)能方便的找到对应的node,所以只好将id也保存下来
                treeNodes.push({
                    "id":node.id,
                    "text":node.text
                });
                //每次对treeNodes的操作都要保存到cookie中
                //注意:treeNodes需要转化为string才能保存到cookie中
                $.cookie("treeNodes",JSON.stringify(treeNodes));
            }
        }
    });        

  3.为tabs组件添加onClose事件,每次关闭一个tab,删除一个对应的值

    /*
     * 初始化内容区的tabs
     */
    $("#home-tabs").tabs({
        fit : true,
        border : false,
        //为其附加鼠标右键事件
        onContextMenu: function(e, title, index){
            e.preventDefault();
            var mm = $("#home-tabs-menu");
            //显示右键菜单
            mm.menu("show",{
                top: e.pageY,
                left: e.pageX
            }).data("tabTitle",title);
            //为右键菜单选项绑定事件
            mm.menu({
                onClick: function(item){
                    closeTab(this, item.name);                    
                }
            });
        },
        //每次关闭tab页时,删除treeNodes中对应的值
        onClose: function(title, index){
            for(var i=0; ; i++){
                if(treeNodes[i].text == title){
                    treeNodes.splice(i,1);
                    $.cookie("treeNodes",JSON.stringify(treeNodes));
                    break;
                }
            }
        }
    });

 四.总结与说明

  在修复过程中,引用了jquery.cookie.js来操作cookie。

  这个变量应该和页面无关,只和会话有关,所以可以有两种方式来处理,一种是发送到后台,保存到session中,另一种是保存到cookie中,我这里使用的是后面一种方法。

  其中最容易出问题的就是json对象和string的转换,我们在程序中,treeNodes是json数组对象,而cookie保存的只能是string对象,所以这两者之间的转换一定要注意,而我就在这里折腾了好久好久。。。

五.后记

  #2016-03-14

  在使用过程中,发现了一个bug。在多选项卡类型的浏览器中,如果只关闭选项卡而不完全关闭浏览器,则会造成再次打开网页后,tab页会恢复到原来的状态,即关闭选项卡再打开,相当于刷新页面。

我也尝试过js监听网页关闭和刷新,可是最终发现,只能区分只有一个选项卡的浏览器关闭和刷新事件,对于多选项卡则无能为力。

posted @ 2016-03-09 18:41  向东方  阅读(1538)  评论(0编辑  收藏  举报