我创建了一个Web应用程序,利用
脚本本身几乎完美地工作;它可以正确加载页面,并在需要时抛出页面错误。然而,我注意到一个奇怪的问题,即
例如,假设我按以下顺序操作:
1. 加载index.php(历史记录将为:Index) 2. 转到profile.php(历史记录将为:Profile、Index) 3. 转到search.php(历史记录将为:Search、Search、Index) 4. 转到dashboard.php 最后,我的历史记录将显示如下(按最近到最旧排序):
Dashboard Dashboard Dashboard Search Index
这样做的问题是,当用户单击向前或向后按钮时,他们要么被重定向到错误的页面,要么必须单击多次才能返回一次。此外,如果他们去检查他们的历史记录,这也没有任何意义。
这是我目前的进展:
history
pushState
和replaceState
方法来在更新历史记录的同时导航页面。脚本本身几乎完美地工作;它可以正确加载页面,并在需要时抛出页面错误。然而,我注意到一个奇怪的问题,即
pushState
会将多个重复的条目(并在之前替换条目)推入历史记录中。例如,假设我按以下顺序操作:
1. 加载index.php(历史记录将为:Index) 2. 转到profile.php(历史记录将为:Profile、Index) 3. 转到search.php(历史记录将为:Search、Search、Index) 4. 转到dashboard.php 最后,我的历史记录将显示如下(按最近到最旧排序):
Dashboard Dashboard Dashboard Search Index
这样做的问题是,当用户单击向前或向后按钮时,他们要么被重定向到错误的页面,要么必须单击多次才能返回一次。此外,如果他们去检查他们的历史记录,这也没有任何意义。
这是我目前的进展:
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
可能会被调用两次,第一次是当你初始化旅行者(window.Traveller = new Traveller();
,constructor
->init
->send
->render
->updateHistory
)时,然后也会通过click
事件监听器中的redirect
调用。我还没有测试过,只是猜测,所以将其添加为评论而不是答案。 - Akshit Arorawindow.Traveller = new Traveller();
将在每次页面重定向时执行,重置window.Traveller
和updateHistory()
函数中的this._initialised
值。不确定这是否是您期望的行为。 - Anis R.