这里有新鲜出炉的 Javascript 教程,程序狗速度看过来!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分)。接下来通过本文给大家介绍 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 类吧:
- (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 保存页面状态的技巧,希望对大家有所帮助!
来源: http://www.phperz.com/article/17/0407/266109.html