自定义后退按钮基于历史记录

时间:2013-06-11 22:08:34

标签: javascript angularjs history.js html5-history

在我的单页网络应用程序中,我希望在某些页面上有一个后退按钮,用户可以将用户带回浏览器历史记录中的特定点:不一定是上一页。

请注意,我不是在谈论浏览器的后退按钮,它应该照常工作。

使用案例

例如,请考虑使用gmail Web应用程序。有一个文件夹视图,可能带有搜索过滤器或其他参数,然后是一个显示单个消息的消息视图。在消息视图中,有一个后退按钮,不会将您带到上一页:即使您已经点击阅读多个消息,后退按钮将返回到您最初来自的文件夹视图,然后单击任何消息。

在gmail的情况下,这是通过简单地编码URL末尾的先前状态来实现的。例如,如果你通过搜索得到这个消息,它将是:

#search/stuff/<MESSAGE_ID>

由此,应用程序知道后退按钮应指向包含以下内容的页面:

#search/stuff

但是,在我的应用程序中,在URL中对所有内容进行编码的状态太多。而不是两个视图(文件夹+消息),有三个视图,让我们称之为A,B和细节,A和B都有一大堆可能的过滤器和URL中编码的选项,我想保留在例如从B返回到A或从详细信息返回到B.在详细信息页面的URL中编码A,B和详细信息的所有参数会使URL非常难以处理。

实施

我认为使用html5历史记录API可以很容易地实现这一点。但是,据我所知,历史API不支持阅读历史记录中的URL:您只能盲目地返回或转发。

history.js可以访问过去的州,如相关问题所述:

History API: Javascript Pushstate, get previous URL

但是,我使用的angularjs与history.js不兼容,因为它直接与历史api对话而不是通过history.js,因此由角度$ location服务引起的转换状态不显示在history.js'历史对象。

似乎我需要做以下其中一项:

  • 让history.js与angular
  • 一起使用
  • 在我自己的代码中重新实现history.js的一部分功能

我还考虑使用document.referrer查看历史记录中的上一个值,但这不起作用,因为在单页应用程序中导航时没有设置它。

2 个答案:

答案 0 :(得分:0)

我从未使用过angular.js,但是如果你想要保证工作的话,大概就是window.history.pushState。请仔细阅读http://spoiledmilk.com/blog/html5-changing-the-browser-url-without-refreshing-page/,了解宝宝可以做些什么的详细信息。

答案 1 :(得分:0)

回答我自己的问题,我选择了@MaxArt在评论中提出的更简单的解决方案。

  • 为页面生成随机ID
    • 由于我使用angularjs,我这样做$ on('$ routeChangeSuccess')或$ on('$ routeUpdate')
    • 没有angularjs,我想我会在onpopstate上做这个
  • 将此随机ID的映射存储到sessionStorage中我需要的所有URL信息(在我的情况下,搜索和路径)
  • 在我的应用的概念层次结构中包含来自= 当前页面的ID 的搜索参数
  • 单击自定义后退按钮时,使用from seach参数在sessionStorage中查找我来自的状态
    • 如果找到,请返回该网址
    • 如果未找到(用户直接导航到此页面),请返回应用层次结构中上一个视图的默认网址

采用这种方法构建过去网址历史记录的更一般方法的基本原理:

  • 如上所述,pushState API不提供对过去URL的访问
  • 将确实提供该信息的History.js集成到angularjs中似乎并不简单
    • angularjs在内部使用历史记录API:需要将其更改为使用历史记录
  • 实现自定义代码以记录sessionStorage中的URL历史记录也不是一件容易的事。主要问题是,由于缺乏与浏览器历史记录的集成,似乎没有一般方法可以知道访问过的页面是新的还是通过返回浏览器历史记录中的一个或多个步骤来访问它。如果有人能提出解决方案(1)
  • ,我很乐意对此予以纠正
  • 使用History.js或任何包含所有history.pushState和其他代码的等效解决方案,几乎所有页面上的链接都要包含在History.pushState中,否则URL更改不会显示在历史记录中。

(1)How do I retrieve if the popstate event comes from back or forward actions with the HTML5 pushstate?