如何判断是否使用popstate事件按下了向前或向后按钮

时间:2013-05-17 15:00:15

标签: javascript angularjs

我一直在做一些研究,似乎popstate事件会在历史记录发生变化的任何时候触发,但似乎没有内置的方法来确定用户是否点击了后退按钮或前进浏览器中的按钮。

我的用例是,当回到历史记录中或在历史记录中前进时,我在ajax应用程序中转换路径时会出现方向动画。我需要确定用户是向后还是向前,这样动画才有意义。令人遗憾的是,popstate事件不支持事件的发展方向。

我还会提到我的应用程序是一个AngularJS应用程序,以防有特定角度的答案,尽管更通用的javascript解决方案是最佳的。

1 个答案:

答案 0 :(得分:4)

我不确定哪种理解是正确的,但我对HTML5 pushstate的理解是不同的。

推送状态支持只允许您捕获浏览器URL中的更改,否则这些更改将作为请求发送到服务器(您或其他人)。目的不是给你"前进"和"返回"事件,但更像是一般的"位置变化"事件。然后,您的应用程序的工作是检查URL并确定用户尝试去的位置。

以这种方式思考:如果用户点击了您要使用javascript处理的应用中的链接,该怎么办?你会有一些事件处理程序设置,它会捕获点击并以某种方式操纵你的应用程序。所以点击"返回"或"转发"就像点击一个链接,但你得到的只是用户试图查看的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问题上的Backbone代码。我仍在学习The Angular Way,并且来自形成我对pushstate的理解的Backbone背景。

回答你的问题

如果您的视图形成某种层次结构或顺序,则可以将其存储在全局变量中。也许您决定为每个视图提供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);
}