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保存页面状态的技巧,希望对大家有所帮助!

html 修改按回退键的url,location.hash保存页面状态的技巧相关推荐

  1. location.hash属性介绍

    location.hash属性介绍 例如URL: http://wwww.a.com/index#rhythmk 通过location.hash 我们将获取到 #rhythmk. 默认浏览器会滚动至i ...

  2. react-router的使用(一)——URL的hash、HTML5的history、Router的基本使用

    一.阶段一:后端路由阶段 早期的网站开发整个HTML页面是由服务器来渲染的. 服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示. 但是, 一个网站, 这么多页面服务器如何处理呢? 一个页 ...

  3. ajax实现浏览器前进后退-location.hash与模拟iframe

    为什么80%的码农都做不了架构师?>>>    Aajx实现无数据刷新时,我们会遇到浏览器前进后退失效的问题以及URL不友好的问题. 实现方式有两种 1.支持onhashchange ...

  4. 利用jsonp、iframe和location.hash解决跨域问题

    几种解决js跨域的方法 js的跨域:由于浏览器同源策略,凡是发送请求url的协议.域名.端口三者之间任意一 与当前页面地址不同即为跨域.如下示例: URL 说明 是否允许通信 http://www.a ...

  5. JS BOM之location.hash详解

    location.hash详解 去年9月,twitter改版. 一个显著变化,就是URL加入了"#!"符号.比如,改版前的用户主页网址为 http://twitter.com/us ...

  6. 获取url的hash值

    location是javascript里边管理地址栏的内置对象,比如location.href就管理页面的url,用location.href=url就可以直接将页面重定向url. 而location ...

  7. window.location.hash属性介绍

    location是javascript里边管理地址栏的内置对象,比如location.href就管理页面的url,用location.href=url就可以直接将页面重定向url.而location. ...

  8. javascript如何对location.hash过滤xss跨站脚本

    场景: 需要获取类似如下url的hash值并做跳转: http://www.xxx.com/home#/comments?type=0 改进前: (function() {var originalUr ...

  9. Vue(小码哥王洪元)笔记06路由,url的hash,history,router-linke,路由跳转,动态路由,懒加载,路由嵌套,router参数传递,导航守卫

    1.什么是路由 路由器提供了两种机制:路由和传送 路由:数据报从来源到目的地的路径 传输:将输入端的数据转移到合适的输出端 路由有一个非常重要的概念教路由表 路由表本质上就是一个映射表,决定了数据包的 ...

最新文章

  1. Windows系统回顾之Windows NT
  2. WEB程序员需要掌握的十大MySQL优化技巧
  3. [阅读笔记] Java 7 新特性
  4. 1070 结绳 (25 分
  5. LeetCode 329. 矩阵中的最长递增路径(记忆化递归)
  6. python os path isfile_Python path.isfile方法代码示例
  7. KaTeX parse error: No such environment: align
  8. android开发比例图表,Android开发中如何使用绘制图表
  9. 转载:互联网盈利模式
  10. swift3.0 coreData的使用-日记本demo
  11. 【Tensor】(张量)的基本概念和操作
  12. Your port 80 is actually used by : Server: Microsoft-IIS/10.0 Cannot install the Apache service, p
  13. 信贷风控四:高校地址自动化识别
  14. CS229 Lecture 20
  15. 微信小程序 黑色背景 页面跳转闪屏
  16. CSS backdrop-filter 实现毛玻璃效果 无需定位裁剪图片
  17. 小鸡小猪大历险java_小鸡和小猪
  18. 接入层、汇聚层、核心层交换机三者之间的功能详解
  19. idm老是下载到99多就停止了 idm下载中断后无法继续下载
  20. 深圳高新技术企业补贴政策及有何好处,补贴30万

热门文章

  1. python读取txt中的一列称为_python读取中文txt文本的方法
  2. “macOS Catalina下TeXstudio内置PDF阅读器无法正常显示中文”的解决办法
  3. 【第一章】MySQL数据概述
  4. centos mysql 修改mysql用户密码
  5. UVA 1264 - Binary Search Tree(BST+计数)
  6. Angular - ng-repeat高级用法
  7. ASP.NET页面之间传值Session(2)
  8. 仿QQ校友DIV模拟窗口
  9. 在.NET环境禁止别人调用代码
  10. PAT乙级(1007 素数对猜想)