使用location.hash保存页面状态
hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分)。
语法
location.hash
在我们的项目中,有大量ajax查询表单+结果列表的页面,由于查询结果是ajax返回的,当用户点击列表的某一项进入详情页之后,再点击浏览器回退按钮返回ajax查询页面,这时大家都知道查询页面的表单和结果都回到了默认状态。
如果每次返回页面都要重新输入查询条件,或有甚者还得转到列表的第几页,那这种体验用户真的要抓狂了。
在我们的项目中,写了一个很简单的JavaScript基类来处理location.hash从而保存页面状态,今天在此就分享给大家。
(本文的内容可能对于JavaScript初学者来讲有点难度,因为涉及到JS面向对象的知识,如定义类、继承、虚方法、反射等)
先看看我们的需求
我们的项目是一个基于微信的H5任务管理系统,要完成的页面原型如下图所示:
需求应该都很清晰,就是点击查询表单,用ajax返回查询结果,然后点击列表中的某一个任务进入任务详情页。由于管理员(项目经理)通常会一次处理多个任务,所以就会不断在任务详情页跟查询列表页切换,这时如果按返回键不能保存查询页面状态的话,那每次返回查询页面都要重新输入查询条件,这样的体验肯定是不能忍受的。
所以,我们需要想办法将页面状态保存下来,以便用户按回退键的时候,查询条件和结果都还在。
解决思路
保存页面状态的思路有很多啦,但是我们觉得用location.hash应该是最好的方法。
思路如下:
1.用户输入查询条件并点击确定后,我们将查询条件序列化成一个字符串,并通过“#”将查询条件加到url后面得到一个新的url,然后调用location.replace(新的url)修改浏览器地址栏中的地址。
2.当用户按回退键回退到查询页面时,也可以说是页面加载时,将location.hash反序列化成查询条件,然后将查询条件更新到查询表单并执行查询即可。
思路很简单,关键的地方就是location.replace方法,这个方法不仅仅是修改浏览器中地址栏的url,更重要的是会在window.history中替换当前页面的记录。如果不用location.replace方法,那么每次回退都会回退到上一个查询条件。当然,这样的需求可能对某些项目还有用。
最终解决方案
如果本文只是分享上面的解决思路,那价值就不大了。本文的价值应该是我们写的那个虽然简单但是却很强大的JavaScript类。
如果你看明白了上面的解决思路,那就看看这个简单的JavaScript类吧:
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
30
31
32
33
34
35
36
37
38
39
40
|
( function () { if (window.HashQuery) { return ; } window.HashQuery = function () { }; HashQuery.prototype = { parseFromLocation: function () { if (location.hash === '' || location.hash.length === ) { return ; } var properties = location.hash.substr().split( '|' ); var index = ; for ( var p in this ) { if (! this .hasOwnProperty(p) || typeof this [p] != 'string' ) { continue ; } if (index < properties.length) { this [p] = properties[index]; if ( this [p] === '-' ) { this [p] = '' ; } } index++; } }, updateLocation: function () { var properties = []; for ( var p in this ) { if (! this .hasOwnProperty(p) || typeof this [p] != 'string' ) { continue ; } var value = this [p]; properties.push(value === '' ? '-' : value); } var url = location.origin + location.pathname + location.search + "#" + properties.join( '|' ); location.replace(url); } }; })(); |
这个类只有2个方法,HashQuery.parseFromLocation() 方法从location.hash反序列化为HashQuery子类的实例,HashQuery.updateLocation() 方法将当前HashQuery子类的实例序列化并更新到window.location。
可以看到HashQuery这个类没有任何属性,那是因为我们只定义了一个基类,类的属性都在子类中进行定义。这也是符合实际的,因为查询条件都只有在具体的页面才知道有哪些属性。
另外,请注意这里的序列化和反序列化。这里的序列化仅仅是利用JavaScript反射机制将实例的所有字符串属性(按顺序)的值用“|”分隔;而序列化则是将字符串用“|”分隔后,再利用反射更新到实例的属性(按顺序)。
如何使用HashQuery类
使用的时候就非常简单了。
第一步,定义一个子类,将需要用到的查询条件都加到字符串属性当中,如我们的代码:
1
2
3
4
5
6
7
8
9
10
11
|
( function () { window.TaskSearchHashQuery = function () { HashQuery.constructor.call( this ); this .iterationId = '' ; this .assignedUserId = '' ; this .status = '' ; this .keyword = '' ; }; TaskSearchHashQuery.constructor = TaskSearchHashQuery; TaskSearchHashQuery.prototype = new HashQuery(); })(); |
第二步,在查询页面调用HashQuery.parseFromLocation() 和 HashQuery.updateLocation()方法即可。下面的代码是我们完整的查询页面:
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
( function () { var urls = { list: "/app/task/list" }; var hashQuery = null ; var pager = null ; $(document).ready( function () { hashQuery = new TaskSearchHashQuery(); hashQuery.parseFromLocation(); //在这里调用的哦,从location反序列化object updateFormByHashQuery(); $( "#btnSearch" ).click( function () { updateHashQueryByForm(); hashQuery.updateLocation(); //在这里调用的哦,将查询条件序列化之后更新到location.hash $( "#lblCount" ).html( "加载中..." ); pager.reload(); page.hideSearch(); }); pager = new ListPager( "#listTasks" , urls.list); pager.getPostData = function (index) { return "pageIndex=" + index + "&pageSize=" + "&projectId=" + page.projectId + "&iterationId=" + hashQuery.iterationId + "&assignedUserId=" + hashQuery.assignedUserId + "&status=" + hashQuery.status + "&keyword=" + hashQuery.keyword; }; pager.onLoaded = function () { $( "#lblCount" ).html( "共 " + $( "#hfPagerTotalCount" ).val() + " 个任务" ); $( "#hfPagerTotalCount" ).remove(); }; pager.init(); }); function updateHashQueryByForm() { hashQuery.iterationId = $( "#ddlIterations" ).val(); hashQuery.assignedUserId = $( "#ddlUsers" ).val(); hashQuery.status = $( "#ddlStatuses" ).val(); hashQuery.keyword = $( "#txtKeyword" ).val(); }; function updateFormByHashQuery() { $( "#ddlIterations" ).val(hashQuery.iterationId); $( "#ddlUsers" ).val(hashQuery.assignedUserId); $( "#ddlStatuses" ).val(hashQuery.status); $( "#txtKeyword" ).val(hashQuery.keyword); }; })(); |
总结
今天在做需求时查询了一些资料总结了一下.
以上内容是小编给大家介绍的location.hash保存页面状态的技巧,希望对大家有所帮助!
使用location.hash保存页面状态的更多相关文章
- 巧用location.hash保存页面状态
在我们的项目中,有大量ajax查询表单+结果列表的页面,由于查询结果是ajax返回的,当用户点击列表的某一项进入详情页之后,再点击浏览器回退按钮返回ajax查询页面,这时大家都知道查询页面的表单和结果 ...
- 简单使用location.hash的方法 ,怎么做,有什么用? 简单的js路由页面方法。
hash 属性是一个可读可写的字符串,该字符串是URL的锚部分(从#号开始的部分).语法location.hash刚开始我真不知道hash有什么用,直到我在项目中遇上一个最大的问题.而且很恶心的体验 ...
- 前端 | Vue 路由返回恢复页面状态
需求场景:首页搜索内容,点击跳转至详情页,页面后退返回主页,保留搜索结果. 方案:路由参数:路由守卫 需求描述 在使用 Vue 开发前端的时候遇到一个场景:在首页进行一些数据搜索,点击搜索结果进入详情 ...
- location.hash来保持页面状态
/*本例是为了在客户端页面返回时保存状态,采用hash值记录的模式,为了使用方便所写的存取hash值的库,时间仓促,望指出错误.*/var pageStateHash = { hashArray: [ ...
- window.location.hash 页面跳转,精确定位,实例展示:
window.location.hash 页面跳转,精确定位,实例展示: (1).index.phtml,页面用于传参 <script id="bb_list_template&quo ...
- window.location.hash(hash应用)---跳转到hash值制定的具体页面
location是javascript里边管理地址栏的内置对象,比如location.href就管理页面的url,用location.href=url就可以直接将页面重定向url.而location. ...
- window.location.hash 使用说明
本文给大家详细汇总了关于window.location.hash的知识点,属性以及用法等等,非常的实用,并附上了例子,有需要的小伙伴可以参考下. location是javascript里边管理地址 ...
- window.location.hash 使用
[转]http://www.cnblogs.com/nifengs/p/5104763.html location是javascript里边管理地址栏的内置对象,比如location.href就管理页 ...
- 学习笔记:location.hash和history.pushState()
在浏览器中改变地址栏url,将会触发页面资源的重新加载,这使得我们可以在不同的页面间进行跳转,得以浏览不同的内容.但随着单页应用的增多,越来越多的网站采用ajax来加载资源.因为异步加载的特性,地址栏 ...
随机推荐
- python类可以任意添加属性
python类可以任意添加属性 class A(object): def __init__(self): self.name = "zhangsan" self.age = 18 ...
- java组件学习15天
Linuxdocker redminegitlabnginxmavenkibanakafkaspringspring cloudLucene 搭建基本使用
- 002-shell变量定义、使用、字符串、数组、注释
一.变量定义 定义变量时,变量名不加美元符号($) name="lhx" 注意,变量名和等号之间不能有空格.同时,变量名的命名须遵循如下规则: 命名只能使用英文字母,数字和下划线, ...
- HI35xx平台调试笔记
1.音视频数据循环采集 a. 在sample_venc.c文件中,海思官方是把采集到的数据都保存到文件中,我们需要更改到缓存里,以便后面推送到rtsp/rtmp/hls服务端. ; i < s3 ...
- usb-tooltip 重写.tooltip { word-break: break-all; }解决单词内换行
<div style="padding: 5px 10px; font-size: 16px; text-align: left" class="truncate& ...
- Eclipse jvm启动参数在哪设置
学习并转载自https://jingyan.baidu.com/article/624e7459653ca534e8ba5a26.html Java是一门非常受欢迎的编程语言,Java的开发人员多数使 ...
- 不允许有匹配 "[xX][mM][lL]" 的处理指令目标
八月 , :: 上午 org.apache.tomcat.util.digester.SetPropertiesRule begin 警告: [SetPropertiesRule]{Server/Se ...
- windows7上安装php7和apche2.4
windows7在配置php7+apache2.4 1.下载并安装vc14http://www.microsoft.com/zh-cn/download/details.aspx?id=48145下载 ...
- C++、Java、JavaScript中的正则表达式
C++(VS2013编译器):http://msdn.microsoft.com/zh-cn/library/bb982727.aspx#grammarsummary Java: ...
- node异步流程控制async
1.串行无关联:async.series(tasks,callback); 多个函数依次执行,之间没有数据交换,其中一个函数出错,后续函数不再执行 async.series({ one: functi ...