您好我正在使用
Javascript开发自己的路由器API.它基于#FregmentIdentifiers(document.location.hash)进行路由.
api完成了almos,但我仍然在做backbuttom事件.每当按下后退按钮并且哈希值发生变化时,之前就会看到,旧内容将被恢复.
您知道如何保存和恢复所有内容吗?
我的问题是,如果我保存并恢复document.body.innerHTML,只会恢复标记,但不会恢复事件,例如googlemaps停止工作.
我试图克隆document.body或document.documentElement,但javascript或者告诉我该字段没有setter或者我的克隆无效.
编辑:
为了明确我正在做的事情,我决定发布我当前的代码.
问题针对标有// Todo评论的部分.
function Router(){
var that = this;
var router = this;
var executionObservers = [];
that.routes = [];
this.registerRoute = function(route){
that.routes.push(route);
};
var history = null;
this.init = function(){
var i;
var identifier = document.location.hash;
history = new History();
history.start();
if(identifier.length > 0){
identifier = identifier.substring(1,identifier.length);
for(i = 0; i< that.routes.length; i++){
var route = that.routes[i];
if(route.contains(identifier)){
route.getAction(identifier)(route.getParams(identifier));
return true;
}
}
}
return false;
};
this.executed = function (identifier){
var i;
for(i=0; i<executionObservers.length; i++){
executionObservers[i](identifier);
}
document.location.hash = identifier;
};
this.addExecutionObserver = function(observer){
executionObservers.push(observer);
};
function History(){
var history = [];
var timeout = 200;
var lastAddedHash = null;
var loop = function(callback){
var hash = window.location.hash;
window.setTimeout(
function(){
if(window.location.hash!=hash){
hash = window.location.hash;
callback(hash);
}
loop(callback);
},timeout
);
};
this.add = function(hash){
lastAddedHash = hash;
window.setTimeout(addCallback(hash),timeout);
};
addCallback = function(hash){
return function(){
var i;
var found = false;
for(i =0; i< history.length&&!found; i++){
if(history[i][1] == hash){
found = true;
//Todo create backup
//history[i][0] =
}
}
if(!found){history.push(new Array(document.documentElement.cloneNode(true),hash));}
}
}
this.setTimeout = function(micoseconds){
timeout = microseconds;
};
started = false;
this.start = function(){
if(!started){
started = true;
loop(function(hash){
var i;
if(lastAddedHash!=null&&hash!=lastAddedHash){
for(i =0; i<history.length; i++){
if(history[i][1] == hash){
//Todo restore from backup
document.location.reload();
}
}
}
});
}
};
router.addExecutionObserver(this.add);
}
}
Router.instance = null;
Router.getInstance = function(){
if(Router.instance === null ){
Router.instance = new Router();
}
return Router.instance;
};
/**
* @param getParams = function(identifier)
* @param getIdentifier = function(params)
* @param contains = function(identifier)
*/
function Route(action,getParams,getIdentifier,contains){
var that = this;
var router = Router.getInstance();
this.contains = contains;
this.getParams = getParams;
this.getAction = function(){
return action;
}
this.reExecute = function(identifier){
action(getParams(identifier));
};
this.execute = function(params){
action(params);
this.executed(params);
}
this.executed = function(params){
router.executed('#' + getIdentifier(params));
};
this.register = function(){
router.registerRoute(this);
};
}
function PrefixedRouterConfig(prefix,paramRegexes){
this.contains = function(identifier){
var regex = "^" + prefix;
for(var i=0;i<paramRegexes.length;i++){
regex+="_"+paramRegexes[i];
}
regex +="$";
var match = identifier.match(regex);
return match != null && (typeof match) == 'object' && (match[0] == identifier);
};
this.getIdentifier = function(params){
ret = prefix;
for(var i=0;i<params.length;i++){
ret+="_"+params[i];
}
return ret;
};
this.getParams = function(identifier){
var regex = "^" + prefix;
for(var i=0;i<paramRegexes.length;i++){
regex+="_("+paramRegexes[i]+")";
}
regex +="$";
var matches = identifier.match(regex);
var ret = [];
for(var i=1;i<matches.length;i++){
ret.push(matches[i]);
}
return ret;
};
}
我的api的示例用法可能如下所示:
config = new PrefixedRouterConfig('show_map',new Array("\\d+","-?\\d+(?:\\.\\d+)?","-?\\d+(?:\\.\\d+)?"));
var ROUTE_SHOW_MAP = new Route(
function(params){
var zoom = params[0];
var lat = params[1];
var lng = params[2];
MyGmapInterface.preparePage(-1);
addTabSelectedCallback(MyGmapInterface.tabLoaded);
addTabClosedCallback(MyGmapInterface.tabClosed);
MyGmapInterface.tabsLoaded = true;
MyGmapInterface.myMap = new MyMap(lat,lng,zoom,MyGmapInterface.getMapContainer(),MyGmapInterface.notCompatible);
MyGmapInterface.addNewCamMarkers(MyGmapInterface.loadCams());
MyGmapInterface.initListeners();
tabSelected(TAB_LEFT);
},config.getParams,config.getIdentifier,config.contains
);
ROUTE_SHOW_MAP.register();
在包含所有Javascript文件(可能注册路由)之后,我调用了Router.getInstance().init();
当我在某处做一个存在路径的ajax请求(手动)时,我调用ROUTE_NAME.executed()来设置fregment标识符并将其注册到历史记录中.
此外,我有一个观察者,只要执行()更改位置哈希,就会更新一些用于直接翻译的链接.
解决方法
这与刷新的情况相同,因此您应该重新使用该系统.
基本上,您的哈希必须包含足够的信息来重建整个页面.当然,有时您需要保存一些用户输入来重建页面.这就是localStorage的用途(IE的userData)