一.问题描述

  使用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监听网页关闭和刷新,可是最终发现,只能区分只有一个选项卡的浏览器关闭和刷新事件,对于多选项卡则无能为力。

easyui修复浏览器刷新后,tab页全部关闭的问题的更多相关文章

  1. H+ 编辑tab页 保存后 刷新列表tab页 并关闭自已。tabA页调用tabB页的方法

    //注:在contabs.js文件中 $(function () { }); 方法外 加入 //注: data-name="' + menuName + '" 这句是加入的自定义属 ...

  2. easyui刷新指定tab页里面的数据

    主页Home/Index中使用tab管理,在主页中设置一个刷新的方法. /** * 刷新指定的tab里面的数据 * @param title 选项卡标题 * @param refreshTabFunc ...

  3. php-fpm正在生成页面时,浏览器刷新后,php-fpm会退出吗?

    好久没写博客了,因为没有啥可写. 之所以有此疑问,是因为看了一篇大牛的文章:PHP升级导致系统负载过高问题分析.看完后,其中有些文字触发了我这个想法,也想验证一下. 方案,用tcpdump抓包,用st ...

  4. easyUI tabs 显示与隐藏 tab 页

    隐藏: tab_option = $('#tabs').tabs('getTab'," 单位信息 ").panel('options').tab; tab_option.hide( ...

  5. chrome浏览器tab页内存占用变大,网站变慢为哪般?

    问题概述: 公司做的是BS应用. 之前我们的后台服务器程序是带状态的,用ehcache存储登录状态:这两天被我改成了redis存储,应用本身不再存储登录状态. 然后自测,我在测试某个很耗时间的网页操作 ...

  6. 使用easyui为tab页增加右键菜单

    在使用easyui进行上左右布局一文中,我们已经使用easyui搭建起了一个简单的上左右布局.在使用的过程中,我们经常会遇到tab页打开的太多,但只能一个一个的关闭的烦恼,这个时候有没有想到eclip ...

  7. easyui中tab页中js脚本无法加载的问题及解决方法

    我发现tab页中<script src="xxx.js">方式加载的脚本没有生效,firebug看请求也没有请求相应的脚本文件. 单独在浏览器中打开tab页中的页面js ...

  8. SPA项目开发之tab页实现

    实现思路及细节 1.利用前面博客所讲的Vuex的知识:定义几个变量 Options:存放tab页对象的容器(主要是路由路径以及tab页的名字) activeIndex:被激活的tab页路由路径 sho ...

  9. 跨浏览器tab页的通信解决方案尝试

    目标 当前页面需要与当前浏览器已打开的的某个tab页通信,完成某些交互.其中,与当前页面待通信的tab页可以是与当前页面同域(相同的协议.域名和端口),也可以是跨域的. 要实现这个特殊的功能,单单使用 ...

随机推荐

  1. MIPS汇编学习

    MIPS汇编学习 mips汇编不同于x86汇编,属于精简指令集,常见于路由器等一些嵌入式设备中. mips汇编没有对堆栈的直接操作,也就是没有push和pop指令,mips汇编中保留了32个通用寄存器 ...

  2. FreeRTOS-05-队列

    说明 本文仅作为学习FreeRTOS的记录文档,作为初学者肯定很多理解不对甚至错误的地方,望网友指正. FreeRTOS是一个RTOS(实时操作系统)系统,支持抢占式.合作式和时间片调度.适用于微处理 ...

  3. Azure Bicep 开发利器

    Bicep 是一种用于声明式部署Azure资源的领域特定语言.它的目标是通过更清晰的语法.改进的类型安全性.以及对模块化和代码重用的更好支持,彻底简化编写体验. Bicep 其实是对 ARM 模板的透 ...

  4. 构建工具之Maven的使用(一)

    一.前言 对于开发一个Java项目,上线之前会通过编译,测试,打包,部署这几个构建过程,如果文件较少,我们可以使用java-->javac-->jar这些命令去完成上述的构建流程.但是当工 ...

  5. Linux系统启动初始化

    文章目录 一.BIOS 加载启动引导程序 二.MBR 主引导扇区 三.GRUB引导内核 3.1运行 boot.img 3.2加载 core.img 3.3切换到保护模式 3.4kernel.img 引 ...

  6. NOIP 模拟 $27\; \rm 牛半仙的妹子序列$

    题解 \(by\;zj\varphi\) 明显一道极长上升子序列的题. 直接线段树维护单调栈,最后单调栈求出可以贡献的序列,答案相加就行. Code #include<bits/stdc++.h ...

  7. 黑马JVM教程——自学笔记(三)

    四.类加载与字节码技术 4.1.类文件结构 首先获得.class字节码文件 方法: 在文本文档里写入java代码(文件名与类名一致),将文件类型改为.java java终端中,执行javac X:.. ...

  8. ApacheDubbo

    一.什么是ApacheDubbo Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能.轻量级的开源 Java RPC 分布式服务框架,它提供了三大核心能力:面向接口的远 ...

  9. c#创建windows服务入门教程实例

    用c#中创建一个windows服务非常简单,与windows服务相关的类都在System.ServiceProcess命名空间下. 每个服务都需要继承自ServiceBase类,并重写相应的启动.暂停 ...

  10. 踩坑记录--接口调用,传参DataTable报错

    问题描述 服务端提供接口,接口参数包含DataTable类型,客户端调用显示请求报错,Postman调用显示Could not get response 解决 原因 接口实现基于wcf,而wcf参数类 ...