3

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

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

用例

例如,考虑 gmail 网络应用程序。有一个文件夹视图,可能带有搜索过滤器或其他参数,然后是一个显示单个消息的消息视图。在消息视图中,有一个后退按钮不会将您带到上一页:即使您单击了几条消息,后退按钮也会将您带回到原来的文件夹视图,然后再单击任何的消息。

在 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,获取上一个 URL

但是,我使用的 angularjs 不适用于 history.js,因为它直接与 history api 对话,而不是通过 history.js,因此由 angular $location 服务引起的转换状态不会显示在历史记录中.js 的历史对象。

看来我需要执行以下操作之一:

  • 让 history.js 与 angular 配合得很好
  • 在我自己的代码中重新实现 history.js 功能的一个子集

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

4

2 回答 2

1

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

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

采用这种方法而不是建立过去 URL 历史的更一般方法的理由:

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

(1)如果 popstate 事件来自带有 HTML5 推送状态的后退或前进操作,我如何检索?

于 2013-06-12T18:30:58.197 回答
0

我从来没有使用过 angular.js,但如果你想要保证工作的东西,大概 window.history.pushState 就是你正在寻找的东西。阅读http://spoiledmilk.com/blog/html5-changeing-the-browser-url-without-refreshing-page/了解有关此婴儿可以做什么的详细信息。

于 2013-06-12T02:56:06.297 回答