响应浏览器地址栏#(hash/fragment)变化
作者:太伯 来源:alipayUED 发布时间:2009-12-28 10:45:00
Gmail 作为一个经典的 Web 2.0 应用,在带来革命性的邮件管理体验的同时,以其完整、快速的 AJAX 操作方式,深受用户的推崇和技术人员的追捧。
技术上,Gmail 通过将用户的操作以 #op1/op2
这样的形式(即 hash 或 fragment, 这里称之为 hash)反映在浏览器地址栏,最后得到一个类似这样的 URL: https://mail.google.com/mail/#inbox
. 它还允许用户直接粘贴这样的地址到达相同的操作界面,并可以通过浏览器的前进/后退按钮在操作步骤之间跳转。
也想尝试一下?先分析一下,通过获取 hash 的值,执行一些操作,即可恢复到该值表示的场景——非常简单。但是,要处理浏览器前进/后退按钮,跳转到相应场景,则有一定困难。因为浏览器不会告诉你 hash 发生变化了。因此,需要实现一个 JavaScript 浏览器导航按钮处理模块。
网上有些代码实现了类似功能,大多感觉冗长复杂。这里,我们介绍支付宝实际应用中开发的一段代码,它的功能简单实用——允许用户指定 hash 发生变化时要做的事情(回调),也可以随时停止它。简单地说,这个代码的原理是,每隔一段时间检查 hash 有没有发生变化,如果有,就运行用户指定的回调方法。代码如下:
// 代码不支持 IE6
historyWatcher = function() {
var timer, last;
return {
register: function(fn, thisObj) {
if(typeof fn !== 'function') return;
timer = window.setInterval(function() {
if(location.hash !== last) {
last = location.hash;
fn.call(thisObj || window, last);
}
}, 100);
},
stop: function() {
timer && window.clearInterval(timer);
},
set: function(newHash) {
last = newHash;
location.hash = newHash;
}
};
}();
以上代码不支持IE6,我们将在解决IE6兼容问题后更新它。
因为它要比较 hash, 所以如果需要更新 hash, 则必须调用 hashWatcher.set()
方法,传入新的 hash。hashWatcher.register()
方法接受两个参数:回调和上下文(可选),hash 发生变化后,新的 hash 会作为唯一的参数传递给回调方法。
hashWatcher的使用方式通常有两部分:
注册回调方法:
hashWatcher.register(function(hash) {
// do something here...
});
必要的时候更新 hash
hashWatcher.set('#op1/obj1');
通常,用于处理 hash 变化的回调 (handler) 只有一个。因此,在设计上,这里只是暴露了一个方法,而不是用采用更复杂的自定义事件的方式。同理,hashWatcher 被设计成一个“静态类”──直接使用,无需实例化。如果需要使用多个回调,可修改上面的代码,让 hashWatcher.register()
返回定时器实例 (timer), 在调用 hashWatcher.stop()
时传入这个 timer.
这段代码仅提供了处理 hash 变化(由应用设置或浏览器导航按键触发)的机制,进一步的恢复操作场景,与具体业务有关,这里就不再讨论了。近期会提供应用于支付宝某项目的实例 (不仅仅是 demo)链接,敬请期待。
猜你喜欢
- 在 Class 块中,成员通过相应的声明语句被声明为 Private(私有成员,只能在类内部调用)
- 二、XML的定义 XML是一个精简的SGML,它将SGML的丰富功能与HTML的易用性结合到Web的应用中。XML保留了SGML的可扩展功能
- 前言:1、上几次讨论右键禁止等问题的时候,有网友问那里有键值表KeyCode,我今天写了一个javascript,以飨各位有需要者。2、适用
- XmlDocume
- 1.新建四个层,放入相应图片,模特层的z-index值设为0。2.把第一个层移到模特身上,找出衣服刚好穿上时层的top和left值,记下来,
- MySQL中模式就是数据库SHOW DATABASES;show databases;罗列所有数据库名称CREATE DATABASE &l
- 为了防止某些别有用心的人从外部访问数据库,盗取数据库中的用户姓名、密码、信用卡号等其他重要信息,在我们创建数据库驱动的解决方案时,我们首先需
- 在Intel的早期,Andy Grove遇到一个雇员 - 他建议公司在芯片的基础上开发个人计算机。AndyGrove疑问道“个人计算机能做什
- 建立资料表:Step1首先开启phpmyadmin,进入wordpress资料库中,并新增一个wp_gbook的资料表与栏位数目8。Step
- 代码如下:'返回指定文件夹中文件的数目,传入值为被检测文件夹的硬盘绝对路径 function CountFile
- 有关JS中字符串的相关文章,现在网上大概不计其数了。这里我不想再就这个问题做过多的论述,只是对几种方式的实现在各种浏览器中的执行效率进行对比
- 联合结果集 新建临时工数据表 代码如下:CREATE TABLE T_TempEmployee (FIdCardNumber VARCHAR
- 不可否认,阿里巴巴走得越来越快也越来越好。技术的成熟让很多B2B B2C网站都在跟风学习它们。在这里我就来说一说它的搜索效果吧。如图所示:&
- 今天下午主要做了个实验,是针对 测试表的列,进行添加,修改,删除的。做法如下: 增加一列: alter table emp4 add tes
- 代码如下:<%@ Language=VBScript %> <% Dim 
- 创建一个表T_Employee并插入若干数据 代码如下:create table T_Employee(FNumber VARC
- 有时候我们可能不知道一个用户的密码,但是又需要以这个用户做一些操作,又不能去修改掉这个用户的密码,这个时候,就可以利用一些小窍门,来完成操作
- “博客就像一本书”这话其实几个月前深圳FB时就有扯到,这也不是什么新概念,也许本身就应该是这样。打个比方,当你拿到一本未看过的书时,理论上你
- 在实现鼠标停在某元素上,会出现提示信息,以前我们太多是采用javascript脚本代码来实现。看了怿飞的IE中伪类:hover的使用及BUG
- 我们现在回到函数上。记得我们用 SUM 这个指令来算出所有的 Sales (营业额)吧!如果我们的需求变成是要算出每一间店 (store_n