我不确定哪种理解是正确的,但是我对 HTML5 pushstate 的理解是不同的。
推送状态支持仅允许您捕获浏览器 URL 中的更改,否则这些更改将作为请求发送到服务器(您的或其他人的)。目的不是为您提供“前进”和“后退”事件,而更像是一般的“位置更改”事件。然后,您的应用的工作就是检查 URL 并找出用户试图去哪里。
这样想:如果用户在您的应用中单击了您想用 javascript 处理的链接怎么办?您将设置一些事件处理程序,它们将捕获点击并以某种方式操纵您的应用程序。所以点击“后退”或“前进”就像点击一个链接一样,但你得到的只是用户试图查看的 URL——没有将事件绑定到的链接。
那么你怎么知道用户想要做什么呢?您可以使用全局变量或您能想到的任何其他方式来管理状态。如果您想减少代码重复,您可以使用 URL 处理 所有 应用程序路由。因此,您的点击处理程序不会绑定到特定链接(或一组链接),而是您可以捕获浏览器 URL 中的更改,然后确定如何处理新 URL。
BackboneJS 使用 Router 对象执行此操作,其中特定路径与特定路由器功能相关联,从而以特定方式设置应用程序的状态,例如:
MyAppRouter = Backbone.Router.extend({
routes: {
'home': 'setupHomeScreen',
'recipes': 'setupRecipesList',
'recipes/:id': 'setupRecipeScreen'
},
setupHomeScreen: function() {
// ...
},
setupRecipesList: function() {
// ...
},
setupRecipeScreen: function(id) {
// ...
},
// ...
});
请原谅关于 Angular 问题的主干代码。我仍在学习 Angular 方式,并且来自 Backbone 背景,这形成了我对 pushstate 的理解。
回答您的问题
如果您的视图形成某种层次结构或顺序,您可以将其存储在全局变量中。也许您决定为每个视图提供 ID,然后每次浏览器状态更改时,您将这些 ID 推送到数组中。
var viewHistory = [];
// ... they visited the recipe list. push it into the history
viewHistory.push('recipeList');
// ... they visited a particular recipe. push it into the history
viewHistory.push('recipe:13');
// ... they clicked the "back" button. we know from the URL that they want
// the recipeList, but we don't know if they're trying to go forward or back.
var nextView = 'recipeList';
if (viewHistory.indexOf(nextView) > 0) {
// *** Back Button Clicked ***
// this logic assumes that there is never a recipeList nested
// under another recipeList in the view hierarchy
animateBack(nextView);
// don't forget to remove 'recipeList' from the history
viewHistory.splice(viewHistory.indexOf(nextView), viewHistory.length);
} else {
// *** They arrived some other way ***
animateForward(nextView);
}