响应浏览器地址栏#(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)链接,敬请期待。 

标签:浏览器,hash,location
0
投稿

猜你喜欢

  • Mootools 1.2教程(7)——设置和获取样式表属性

    2008-11-25 13:48:00
  • Oracle 下的开发日积月累

    2009-02-28 11:08:00
  • 根据时段自动切换你的站点CSS皮肤风格

    2007-09-20 18:08:00
  • 网页绿色系配色应用实例

    2008-08-26 11:51:00
  • 怎样设计网站首页?(解答)

    2007-11-04 18:56:00
  • Rs.Open参数说明

    2008-05-12 22:43:00
  • oracle 存储过程和触发器复制数据

    2009-11-17 09:12:00
  • FrontPage XP设计教程5——表单的设计

    2008-10-11 12:35:00
  • 适合所有表的添加、删除、修改的函数

    2008-04-15 15:29:00
  • 分享一些可视信息设计资源

    2009-10-06 15:19:00
  • 为导入文件加上时间戳标记的两种方法

    2009-01-07 14:14:00
  • ASP网站数据采集经验谈

    2008-03-09 15:30:00
  • Oracle字符集修改查看方法

    2009-11-05 21:45:00
  • 十个简单好用的设计技巧[译]

    2009-04-08 12:56:00
  • 发布淘宝开源编辑器 KISSY Editor 1.0.0

    2009-10-27 16:20:00
  • 从Oracle 表格行列转置说起第1/2页

    2009-09-24 12:51:00
  • W3C web标准概念入门

    2008-05-25 15:06:00
  • oracle下加密存储过程的方法

    2009-02-28 10:50:00
  • ASP代理采集的核心函数代码

    2010-01-02 20:43:00
  • WEB2.0网页制作标准教程(2)什么是名字空间

    2007-11-13 13:04:00
  • asp之家 网络编程 m.aspxhome.com