你好,我正在用Javascript開發我自己的路由器API。它基於#FregmentIdentifiers(document.location.hash)進行路由。如何使用Javascript保存和恢復整個網站?
該api是almos完成,但我仍然在backbuttom事件工作。每當按下後臺按鈕並且哈希已經改變並且之前被看到時,舊內容將被恢復。
您是否知道一種保存和恢復所有內容的方法?
我在這裏的問題是,如果我保存和恢復document.body.innerHTML只有標記被恢復,但不是事件,例如, Google地圖停止工作。 我想克隆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標識符並註冊它的歷史記錄。
而且我有一個觀測器更新一些鏈接,其中用於直接翻譯,每當位置散列被改變()執行
好吧,我已經開始了這個賞金。 50+對於那個給我這個問題的答案的人,顯示工作代碼。目前,我正在通過簡單的重新加載來解決後退按鈕事件,但我更喜歡的是從歷史記錄恢復。這意味着,標記和事件也可以被存儲和恢復。我只需要這裏的存儲和恢復邏輯。事件處理已經完成。或者你會說,處理它與重新加載更好? 關心和感謝。 – 2011-04-24 15:57:51
你的賞金是浪費時間,你想要做的事情既非常困難也毫無意義。瀏覽器自己處理緩存的歷史頁面,而不是來自網站的「代碼」。您可以使用PHP來恢復前一頁,並傳入一個包含您希望在該頁面上設置的歷史參數的對象。說實話,一個基於片段標識符的'路由器API'聽起來可怕並且是史前的,你應該再投入一些時間來學習現代網絡實踐。 – GAgnew 2011-04-26 17:29:28
我有一個JavaScript代碼,它爲每個ajax請求設置了唯一的細分標識符。通過細分標識符,整個頁面可以恢復。但是目前的後退按鈕在沒有重新加載的情況下無法運行。 – 2011-04-28 16:49:29