如何在单页移动Web应用程序中实现自己的历史堆栈?

时间:2012-06-01 07:34:20

标签: javascript mobile backbone.js browser-history zepto

我有一个使用Backbone和Zepto开发的单页移动应用程序。

它可以正常使用浏览器中的后退/前进按钮。

当用户导航到某个页面时,内容会从右侧滑入,因为内容会向左滑动(并从视口中移出)。如果用户按下“前进”浏览器按钮,我希望发生同样的事情。一切正常。

我有一个我添加到body元素navigate-back的类会触发这种行为,因此当用户使用浏览器的后退按钮导航回来时,他们会看到内容滑动返回从左边开始,其他内容向右滑动。基本上与前进相反。

我需要检测用户是否向后导航,以便我可以调用替代行为。我已经尝试过实现我自己的历史堆栈,但是我遇到了很多问题,有时它会将前进标记为后退导航,这会破坏视觉提示。它现在变成了一堆黑客,如果我发布它可能只会让我感到尴尬。

实现我自己的历史堆栈的最佳方法是什么,以便我可以检测用户是否在单页Backbone移动应用程序的上下文中向前/向后导航?

5 个答案:

答案 0 :(得分:22)

我不知道backbone.js 1 ,但我帮助开发了一个必须在html5中实现这种行为的移动应用程序,所以我应该可以给出一些好的建议:

首先,知道history.pushState函数存在是件好事。但问题是it is supported up to android 2.3, but not on android 3 till android 4.0.3。正如kiranvj指出的那样,这可以通过使用流行的history.js库来解决,该库为缺乏历史功能提供了polyfill解决方案。

现在,了解实际问题,我实现历史方向动画的方法是将数据添加到pushState函数(history.pushState(data,title,url))中,并使用该函数确定页面的逻辑位置。在我的应用程序中,我不仅限于水平条,但在您的情况下,您将跟踪任何新加载页面的位置,该位置比当前页面高一个位置。 E.g。

History.pushState({position:History.getState().data.position+1},"Your title","Your URL");

接下来,当window.onstatechangewindow.onanchorchange事件触发时,您会观察位置是高于还是低于当前页面(例如,使用history.js History.getState()功能我在上面使用了)并根据这个你决定移动的方向(左边是下边,右边是更高),如下图所示:

Illustration of history events

您还会注意到我已在第一页上假设您有{position:1},而通常第一页将没有州信息。实现这一目标的方法是使用history.replaceState将当前空状态替换为信息量更大的状态。或者,您也可以检查前面提到的任何事件的空状态,如果它是空的,则认为它是最左边的事件({position:1})。

希望这会有所帮助,如果您有任何其他问题,请随时提出。

请注意,此答案假定您使用的是history.js,您需要收听略有不同的事件(例如onpopstate)并使用稍微不同的结构(history而不是{ {1}})如果你想建立自己的解决方案。

还可以注意到,可以使用自己的队列数组构建它,这样可以提供更多控制,但不能与浏览器的后退按钮结合使用。这是浏览器网站的一个大问题,但是如果您要构建cordova(a.k.a。phonegap)网络应用程序,则会更容易。


1只是阅读它并且似乎做了一些历史记录处理of its own可能使集成上述技术变得更加复杂。 < / p>

答案 1 :(得分:1)

我在移动设备上使用Zepto时遇到了同样的问题 - 单页 - 多个视图。

最初我使用了html5 statechange和onhashchange。在一个或其他移动设备中都存在一些问题。最后我从这里使用了Zepto历史插件https://github.com/browserstate/history.js

它解决了大部分问题。尝试一下,它会很有用,它会尽可能地处理html4和html5功能。

答案 2 :(得分:1)

如果您正在使用 true 单页应用,那么为什么不设置一个数组来保存js变量中的历史记录网址(而不是像{{1}那样依赖和它的支持)?

每当导航到新页面时,您可以将其网址推入数组,只要按下“后退”按钮,您就可以根据需要检索所需的网址。只要您在用户返回几个步骤然后导航到链接时正确丢弃网址,这将完美地工作。

我从来没有尝试过将其用于页面历史记录,但这对于页面内的undo-redo逻辑非常有效。

更新

经过进一步的研究,上面的方法不适用于页面重新加载,因为它可能是通过JS提供的历史记录处理之外发生的操作。它仍可用于跟踪后退/前进过渡,但在导航到应用程序外部的URL或页面刷新时,此类历史记录将丢失。 David Mulder的答案似乎缺乏这种限制,依赖于页面范围之外的浏览器级历史记录。

答案 3 :(得分:0)

在单页移动应用程序中使用此功能,这将允许历史记录并将用户移回。

{{1}}

答案 4 :(得分:-2)

Sammy.js的v.6.x分支(仅依赖于哈希变化的分支)是跟踪历史记录的完美,最简单,最兼容浏览器的方法。在那里,历史根本没有被跟踪,因为Sammy只是在监视哈希变化。

依靠“#/ slide / 123”可以支持硬页面重新加载,并简化工作

剥离每个页面视图的最后一部分(幻灯片编号),推入全局。在新路线上,查看数字是否多于或少于全局存储的数量,并执行正确的(左或右)动画。如果未定义全局,则不进行动画。