【问题标题】:How to keep a clean browser history in a backbone.js app?如何在backbone.js 应用程序中保持干净的浏览器历史记录?
【发布时间】:2012-04-11 23:51:53
【问题描述】:

我的backbone.js有三个视图:

  1. 类别列表
  2. 类别中的项目列表
  3. 单个项目的表格

我正在使用backbone.js 路由器在这些视图之间导航。应用程序中的用户流转到 12、23 和 3 --> 1。用户可以使用浏览器的后退和前进按钮来回导航,这是想要的行为。对任何项目的深层链接也有效。

问题是我想保持历史整洁。这是一个示例使用流程:

  • 用户打开类别列表。历史记录:“类别列表”(正确)
  • 用户选择“我的类别”。历史记录:“我的类别”
  • 用户选择“我的项目”。历史记录:“我的项目”
  • 用户填写表格并保存,被重定向到“类别列表”。历史记录:“类别列表”

另一个例子:

  • 用户打开“我的类别”的网址
  • 用户按下主页按钮。历史记录:“类别列表”

关于如何以干净的方式实现这一点的任何想法?

【问题讨论】:

  • 我认为你应该open your search,这不是关于 Backbone,而是关于 javascript、浏览器标准和安全问题。你会发现一些技巧。
  • 我意识到历史处理是一个浏览器功能,与主干没有直接关系。问题是如何在使用主干路由的应用程序的上下文中操作历史记录。
  • 只是为了澄清我在寻找这个问题和赏金的内容: - 一种使用 history.back()、history.forward() 和 history.replaceState 的方法(或者在这种情况下是路由器。导航(片段,{replace:true})以实现上述用例 - 解决这个用例就足够了,不必是一个全局解决方案 - 我知道我们处于一个有点棘手的领域,但是优雅或至少独立的解决方案受到赞赏
  • 事后,但我决定将我的解决方案重写为开源组件,以防它对其他人有用。可以在github.com/omahlama/historyhelper找到

标签: backbone.js browser-history


【解决方案1】:

无法实现您提供的第一个示例。您无法实现第一个示例,因为无法使用 Javascript 来“删除”浏览器历史记录。

无法清除会话历史记录或禁用非特权代码的后退/前进导航。最接近的可用解决方案是 location.replace() 方法,它将会话历史记录的当前项替换为提供的 URL。

-https://developer.mozilla.org/en/DOM/window.history

您最多可以使用window.location.replacewindow.history.replaceState 阻止将当前页面添加到浏览器历史记录中。 Backbone.js 通过在路由器对象上调用 router.navigate(fragment, [options]) 并在选项中指定 {replace: true} 提供了一种方便的方法。

我会尝试编写一个可以处理显示/隐藏特定视图的主视图,而不是依赖不同的路由来确定要显示的视图。

编辑

好的,进入黑客领域...

由于“类别列表”页面似乎是应该“重置”历史记录的页面,因此我发布的解决方案试图解决您提到的两个用例。该代码跟踪historyState 变量,该变量表示何时访问“类别列表”页面以及之后访问的其他页面。

// in your application init...
$(function(){
    window.historyState = -1;
    router = new Backbone.Router({ 
        routes: {
            "category-list": category-list,
            "category": category,
            "item": item
        }
        
        category-list: function(){
            historyState = 0;
        },
        
        category: function(){
            if(historyState >= 0)
                historyState++;
        },
        
        item: function(){
            if(historyState >= 0)
                historyState++;
        }
    });
});
  • 如果historyState-1 - 我们还没有访问“类别列表”页面。
  • 如果 historyState0 - 我们当前位于“类别列表”页面。
  • 如果historyState 大于0 - 自查看“类别列表”页面以来访问的页面数。

现在每当使用链接导航到“类别列表”页面时,请确保它调用以下方法来处理适当的导航。

function routeToCategoryList(){
  if( historyState > 0 ){ 
    // 'category-list' already exists in our history route to that page.
    window.history.go((historyState * -1));
  } else {  
    // otherwise, don't store an entry for the current page we are on.
    router.navigate("/category-list", {trigger: true, replace: true});  
  } 
}

如果“类别列表”页面已经被访问过,则在历史记录中返回适当数量的条目(不幸的是,这会将其他页面保留在历史记录中,因此您仍然可以继续前进)。否则,如果尚未访问“类别列表”页面,则导航到该页面并确保不要将当前页面添加到历史记录中。

【讨论】:

  • 我认为,为了解决示例用户案例,问题表明您不需要删除浏览器历史记录,而是rewind到初始状态,我认为这是允许的。
  • 我仍然认为旨在实现的行为违反了浏览器的标准,这不会是一条友好的道路。
  • 关于违反浏览器标准:您在技术上是正确的,但这是针对手机的网络应用程序。用户的期望是一个应用程序,而不是一个网页——WP7 和安卓手机的物理后退按钮确实增加了用户界面的易用性。往后按上树感觉很自然,往下到你有背部的叶子感觉不对劲。
  • @OlliM 我很确定你是你反对浏览器标准的理由,我只想说这比这需要加倍努力。
【解决方案2】:

没有办法从主干历史中删除历史,您可以通过获取当前片段添加一些逻辑来重新路由导航

或者您可以使用 history.js(适用于大多数浏览器)

虽然https://developer.mozilla.org/en/DOM/window.history 仅适用于 Mozila firefox,所以这不适用于 Android 应用

【讨论】:

    猜你喜欢
    • 2017-04-14
    • 2012-07-22
    • 2012-02-03
    • 2021-05-27
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    • 2013-01-31
    相关资源
    最近更新 更多