jquery,处理页面前进回退多个状态还原的jQuery hashchange event扩展

在用Ajax做无刷新应用的时候,如果用户使用前进、后退或者跳转到其他页面,再回到原页面时,页面会回到脚本运行前的状态。这是一个老问题,以前总是让用户忍耐一下,今天晚上有点想法,突然想做一下试试,自我感觉还是很有一些价值。 类似Gmail的做法,使用location.hash来存储页面状态,监控hash变化,使用脚本还原浏览状态看起来很不错。有一个JQuery的插件以事件的方式提供了这种监控。jQuery hashchange event,本文也使用这个插件实现对hash变化的监控。 不过仅有这个插件总感觉不太够,页面元素很多,如何判断状态改变的元素,编写对应的状态还原代码,如果都放到hashchange事件里处理,维护起来问题很大。这里参考了Publish/Subscribe的概念,增加了一个事件代理,将状态触发与处理分离。同时,通过状态名来区分不同的状态改变。相应的handler只需要订阅对应的状态名来处理状态改变。
今天有点晚了,我先把代码贴出来吧。
首先是增加一个jquery extend:
var hashChangeBroker = { _subscribs: {}, _oldHash: "", subscrib: function (fragName, handler) { if (!this._subscribs[fragName]) { this._subscribs[fragName] = []; } this._subscribs[fragName].push(handler); }, publish: function (hash) { var frags = hash.match(/\w+\:\w+&/g); var oldFrags = this._oldHash.match(/\w+\:\w+&/g); var changes = {}; for (var i in frags) { var arr = frags[i].split(":"); changes[arr[0]] = { changed: true, state: arr[1].substring(0, arr[1].length - 1) }; } for (var i in oldFrags) { var arr = oldFrags[i].split(":"); if (changes[arr[0]]) { if (changes[arr[0]].state == arr[1].substring(0, arr[1].length - 1)) { changes[arr[0]].changed = false; } } else { changes[arr[0]] = { changed: true, state: "" }; } } for (var key in changes) { if (!changes[key].changed) continue; for (var i in this._subscribs[key]) { this._subscribs[key][i](changes[key].state); } } this._oldHash = hash; }, changeFrag: function (fragName, state) { var frag = fragName + ":" + state + "&"; if (location.hash.length > 0) { var regex = new RegExp(fragName + "\\:\\w+&"); if (location.hash.search(regex) != -1) { location.hash = location.hash.replace(regex, frag); } else { location.hash += frag; } } else { location.hash = "#" + frag; } }, init: function () { this.publish(location.hash); } } $.extend({hashChangeBroker:hashChangeBroker});
在使用的时候,首先需要在$(document).ready里增加对hashchange的处理,需要引用上面提到的插件:
$(window).hashchange(function (e) { $.hashChangeBroker.publish(location.hash); });
订阅状态变更的代码:
//订阅列表页码状态 $.hashChangeBroker.subscrib("userlist", function (state) { //跳转到对应页 alert("change page:" + state); }); //另一个状态 $.hashChangeBroker.subscrib("other", function (state) { //随便怎么处理吧 alert("other state:" + state); });
变更状态的方法,绑定到对应的控件即可,例如button,link之类:
function go(page) { $.hashChangeBroker.changeFrag("userlist", page); } function otherStateChange() { $.hashChangeBroker.changeFrag("other", "somestate"); }
另外,如果需要在页面初次载入时,可以处理hash,可以在$(document).ready里增加如下代码:
//处理初次载入页面带有的hash $.hashChangeBroker.init();
输出的url类似:
http://yourdomain/something/doit#userlist:3&next:somestate&
hash结构由"&"分隔,每段内容":"前是状态名,后面是状态值(状态值由handler自己处理,解释权由你自己来定:)

Tags:  jquery

延伸阅读

最新评论

发表评论