我创建了一个Web应用程序,该应用程序使用history pushState和replaceState方法来浏览页面,同时更新历史记录。
该脚本本身几乎可以完美运行;它将正确加载页面,并在需要抛出页面时抛出页面错误。但是,我注意到一个奇怪的问题,该问题pushState会将多个重复的条目(并替换之前的条目)推送到历史记录中。
例如,假设我(按顺序)执行以下操作:
加载index.php(历史记录为:索引)
导航到profile.php(历史记录将是:Profile,Index)
导航到search.php(历史记录为:搜索,搜索,索引)
导航至dashboard.php
最后,这是我历史上将要发生的事情(按照最新到最旧的顺序):
仪表
板
仪表板仪表板
搜索
索引
这样做的问题是,当用户单击前进或后退按钮时,他们将被重定向到错误的页面,或者必须单击多次才能返回一次。那,如果他们去检查他们的历史记录就没有意义了。
这是我到目前为止的内容:
var Traveller = function(){
this._initialised = false;
this._pageData = null;
this._pageRequest = null;
this._history = [];
this._currentPath = null;
this.abort = function(){
if(this._pageRequest){
this._pageRequest.abort();
}
};
// initialise traveller (call replaceState on load instead of pushState)
return this.init();
};
/*1*/Traveller.prototype.init = function(){
// get full pathname and request the relevant page to load up
this._initialLoadPath = (window.location.pathname + window.location.search);
this.send(this._initialLoadPath);
};
/*2*/Traveller.prototype.send = function(path){
this._currentPath = path.replace(/^\/+|\/+$/g, "");
// abort any running requests to prevent multiple
// pages from being loaded into the DOM
this.abort();
return this._pageRequest = _ajax({
url: path,
dataType: "json",
success: function(response){
// render the page to the dom using the json data returned
// (this part has been skipped in the render method as it
// doesn't involve manipulating the history object at all
window.Traveller.render(response);
}
});
};
/*3*/Traveller.prototype.render = function(data){
this._pageData = data;
this.updateHistory();
};
/*4*/Traveller.prototype.updateHistory = function(){
/* example _pageData would be:
{
"page": {
"title": "This is a title",
"styles": [ "stylea.css", "styleb.css" ],
"scripts": [ "scripta.js", "scriptb.js" ]
}
}
*/
var state = this._pageData;
if(!this._initialised){
window.history.replaceState(state, state.title, "/" + this._currentPath);
this._initialised = true;
} else {
window.history.pushState(state, state.title, "/" + this._currentPath);
}
document.title = state.title;
};
Traveller.prototype.redirect = function(href){
this.send(href);
};
// initialise traveller
window.Traveller = new Traveller();
document.addEventListener("click", function(event){
if(event.target.tagName === "a"){
var link = event.target;
if(link.target !== "_blank" && link.href !== "#"){
event.preventDefault();
// example link would be /profile.php
window.Traveller.redirect(link.href);
}
}
});
感谢所有的帮助,
干杯。
updateHistory。现在,updateHistory在初始化Traveler(window.Traveller = new Traveller();,constructor-> init-> send-> render->-> updateHistory)时,可能会被调用两次,即第一次,也可能是redirect从clickeventListener中调用。我还没有测试过它,只是进行了疯狂的猜测,因此将其添加为注释而不是答案。