location.hash保存页面状态的技巧


Posted in Javascript onApril 28, 2016

hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分)。

语法

location.hash

在我们的项目中,有大量ajax查询表单+结果列表的页面,由于查询结果是ajax返回的,当用户点击列表的某一项进入详情页之后,再点击浏览器回退按钮返回ajax查询页面,这时大家都知道查询页面的表单和结果都回到了默认状态。

如果每次返回页面都要重新输入查询条件,或有甚者还得转到列表的第几页,那这种体验用户真的要抓狂了。

在我们的项目中,写了一个很简单的JavaScript基类来处理location.hash从而保存页面状态,今天在此就分享给大家。

(本文的内容可能对于JavaScript初学者来讲有点难度,因为涉及到JS面向对象的知识,如定义类、继承、虚方法、反射等)

先看看我们的需求

我们的项目是一个基于微信的H5任务管理系统,要完成的页面原型如下图所示:

location.hash保存页面状态的技巧

需求应该都很清晰,就是点击查询表单,用ajax返回查询结果,然后点击列表中的某一个任务进入任务详情页。由于管理员(项目经理)通常会一次处理多个任务,所以就会不断在任务详情页跟查询列表页切换,这时如果按返回键不能保存查询页面状态的话,那每次返回查询页面都要重新输入查询条件,这样的体验肯定是不能忍受的。

所以,我们需要想办法将页面状态保存下来,以便用户按回退键的时候,查询条件和结果都还在。

解决思路

保存页面状态的思路有很多啦,但是我们觉得用location.hash应该是最好的方法。

思路如下:

1.用户输入查询条件并点击确定后,我们将查询条件序列化成一个字符串,并通过“#”将查询条件加到url后面得到一个新的url,然后调用location.replace(新的url)修改浏览器地址栏中的地址。

2.当用户按回退键回退到查询页面时,也可以说是页面加载时,将location.hash反序列化成查询条件,然后将查询条件更新到查询表单并执行查询即可。

思路很简单,关键的地方就是location.replace方法,这个方法不仅仅是修改浏览器中地址栏的url,更重要的是会在window.history中替换当前页面的记录。如果不用location.replace方法,那么每次回退都会回退到上一个查询条件。当然,这样的需求可能对某些项目还有用。

最终解决方案

如果本文只是分享上面的解决思路,那价值就不大了。本文的价值应该是我们写的那个虽然简单但是却很强大的JavaScript类。

如果你看明白了上面的解决思路,那就看看这个简单的JavaScript类吧:

(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类

使用的时候就非常简单了。

第一步,定义一个子类,将需要用到的查询条件都加到字符串属性当中,如我们的代码:

(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()方法即可。下面的代码是我们完整的查询页面:

(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来保存页面状态的全部知识了。不知道大家的WEB项目中是如何处理这样的需求的呢?

以上内容是小编给大家介绍的location.hash保存页面状态的技巧,希望对大家有所帮助!

Javascript 相关文章推荐
JavaScript 基础知识 被自己遗忘的
Oct 15 Javascript
jQuery获取浏览器中的分辨率实现代码
Apr 23 Javascript
JavaScript中的prototype和constructor简明总结
Apr 05 Javascript
基于Bootstrap+jQuery.validate实现Form表单验证
Dec 16 Javascript
使用javascript实现简单的选项卡切换
Jan 09 Javascript
javascript实现拖动元素交换位置
Nov 29 Javascript
jQuery短信验证倒计时功能实现方法详解
May 25 Javascript
require.js配合插件text.js实现最简单的单页应用程序
Jul 12 Javascript
基于JavaScript实现点击页面任何位置返回
Aug 31 Javascript
ajax的分页查询示例(不刷新页面)
Jan 11 Javascript
vue实践---根据不同环境,自动转换请求的url地址操作
Sep 21 Javascript
javascript中导出与导入实现模块化管理教程
Dec 03 Javascript
字符串反转_JavaScript
Apr 28 #Javascript
使用 stylelint检查CSS_StyleLint
Apr 28 #Javascript
基于BootStarp的Dailog
Apr 28 #Javascript
浅析jquery与checkbox的checked属性的问题
Apr 27 #Javascript
JavaScript 消息框效果【实现代码】
Apr 27 #Javascript
浅析jQuery事件之on()方法绑定多个选择器,多个事件
Apr 27 #Javascript
js实现人民币大写金额形式转换
Apr 27 #Javascript
You might like
DOTA2 探索永无止境 玩家自创强悍插眼攻略
2020/04/20 DOTA
全世界最小的php网页木马一枚 附PHP木马的防范方法
2009/10/09 PHP
使用Sphinx对索引进行搜索
2013/06/25 PHP
header导出Excel应用示例
2014/01/24 PHP
php调用google接口生成二维码示例
2014/04/28 PHP
php根据日期或时间戳获取星座信息和生肖等信息
2015/10/20 PHP
基础的WordPress插件制作教程
2015/11/24 PHP
PHP的Yii框架中行为的定义与绑定方法讲解
2016/03/18 PHP
最新最全PHP生成制作验证码代码详解(推荐)
2016/06/12 PHP
Javascript 获取滚动条位置等信息的函数
2009/09/08 Javascript
解析javascript 实用函数的使用详解
2013/05/10 Javascript
JavaScript获取当前cpu使用率的方法
2015/12/15 Javascript
使用jQuery Mobile框架开发移动端Web App的入门教程
2016/05/17 Javascript
分享JavaScript监听全部Ajax请求事件的方法
2016/08/28 Javascript
js微信扫描二维码登录网站技术原理
2016/12/01 Javascript
jQuery 获取select选中值及清除选中状态
2016/12/13 Javascript
js精确的加减乘除实例
2017/11/14 Javascript
jQuery Validate插件ajax方式验证输入值的实例
2017/12/21 jQuery
浅谈vue项目4rs vue-router上线后history模式遇到的坑
2018/09/27 Javascript
微信小程序提交form操作示例
2018/12/30 Javascript
AutoJs实现刷宝短视频的思路详解
2020/05/22 Javascript
Node使用koa2实现一个简单JWT鉴权的方法
2021/01/26 Javascript
[03:42]2014DOTA2西雅图国际邀请赛7月9日TOPPLAY
2014/07/09 DOTA
[07:59]2014DOTA2叨叨刀塔 林熊猫称被邀请赛现场盛况震撼
2014/07/21 DOTA
下载给定网页上图片的方法
2014/02/18 Python
使用python实现rsa算法代码
2016/02/17 Python
Python多进程编程常用方法解析
2020/03/26 Python
浅谈cv2.imread()和keras.preprocessing中的image.load_img()区别
2020/06/12 Python
python 删除系统中的文件(按时间,大小,扩展名)
2020/11/19 Python
html5组织文档结构_动力节点Java学院整理
2017/07/11 HTML / CSS
娇韵诗Clarins意大利官方网站:法国天然护肤品牌
2020/03/11 全球购物
项目副经理岗位职责
2013/12/30 职场文书
职员竞岗演讲稿
2014/05/14 职场文书
“向国旗敬礼”主题班会活动设计方案
2014/09/27 职场文书
初中中等生评语
2014/12/29 职场文书
婚礼答谢词范文
2015/09/29 职场文书