15

我有一个 Web 应用程序,用于存储有关最近访问的页面的信息,我们称它们为 A。当用户访问另一种称为 B 的页面类型时,我会在顶部呈现一个菜单,其中包含一个指向最近访问的 A 页面的按钮。B 页面可以通过 A 页面或 B 页面访问,并且可以被用户视为 A 的属性。

这很好用,但是当有人打开两个选项卡并且在选项卡 1 中的 B 页面上带有指向 A 页面 A1 的链接时,他们会打开一个新选项卡并访问 A 页面 A2,这会成为一个问题。当用户随后刷新选项卡 1 中的 B 页面时,菜单更改为 A2。我希望能够识别正在使用的选项卡,以便我可以为选项卡 1 保存 A1,这样它就不会更改为 A2。

使用一个选项卡时:

A1 -> B1 -> B2 (the menu points back to A1)

使用两个选项卡时:

Time            | T1       | T2       | T3          
----------------+----------+----------+-------------
Tab 1:          | A1 -> B1 |          | [refresh B1]
Tab 2:          |          | A2 -> B3 |             
----------------+----------+----------+-------------
Menu points to: | A1    A1 | A2    A2 | A2

当用户返回选项卡 1 时,这会使用户感到困惑,他们在选项卡 2 (A2) 而不是 A1 中查看的用户。

恐怕无法获得浏览器标签 ID,但有人可能对解决方法有任何想法?

4

3 回答 3

17

HTML5 sessionStorage解决了这个问题:

站点可以将数据添加到会话存储中,并且该窗口中打开的同一站点的任何页面都可以访问这些数据。

所有现代浏览器都支持

另一种方法是使用window.name属性。它是特定于选项卡/窗口的,并且在浏览器导航中保持不变。window.name因此,您可以在您的财产中存储一些标签 ID 之王

于 2015-09-02T08:46:46.833 回答
5

编辑:时间的流逝使我从 2012 年开始的原始答案不正确。正如bedrin 指出的那样,您现在可以使用该Window.sessionStorage对象

sessionStorage 属性允许您访问当前源的会话存储对象。sessionStorage 与 Window.localStorage 类似,唯一的区别是 localStorage 中存储的数据没有设置过期时间,而 sessionStorage 中存储的数据在页面会话结束时会被清除。只要浏览器打开并在页面重新加载和恢复后仍然存在,页面会话就会持续。在新选项卡或窗口中打开页面将导致启动新会话,这与会话 cookie 的工作方式不同。

原始答案(2012):

恐怕这无法以可移植的方式实现,因为您发现自己无法检索浏览器选项卡 ID 之类的东西。据我所知,HTML 标准完全不知道浏览器中的选项卡。

我能想到的唯一解决方法是:在您的应用程序中实现和管理选项卡。我见过几个这样做的商业网络应用程序,但是(恕我直言)用户体验非常糟糕。

于 2012-09-27T11:04:12.630 回答
0

因此,我提出了一种似乎效果很好的解决方案,但事实并非如此。请参阅最后一个问题项目符号。我仍然希望有更好的想法,所以请让我知道你是否继续!

反正; 这就是我的做法。请记住,这不是 100% 万无一失的解决方案,如果用户“行为不端”并同时刷新多个选项卡,它可能会感到困惑:

base.html(所有页面都继承)({{ A }} 呈现来自 Django 的变量):

// This is executed right before leaving the page
window.onunload = function() {
    if( '{{ A }}' != null ) 
        var prev_A = '{{ A }}';
    else if (typeof previous_A != 'undefined') {
        var prev_A = previous_A;
    else 
        var prev_A = '';
    localStorage.setItem('a', prev_A);
};
// Remove the local storage as soon as you get to this page
localStorage.removeItem('a');

B_base.html(所有B的基础模板。B_base.html也继承了base.html。我把这段代码放在base.html中的代码之前执行)

var previous_A = localStorage.getItem('a');

所以基本上我得到的是每个页面在离开页面时设置localStorage'a'并在进入页面后立即删除localStorage'a',除了首先将'a'保存为本地的B页面删除之前的变量。

问题:

  • 同时在多个选项卡中打开链接将覆盖此变量,并且一个选项卡将没有previous_A。
  • 不去任何地方关闭一个A标签,然后直接打开一个新的B页面,会导致B标签的previous_A中有关闭的A的值。
  • 在 A 页面的新选项卡中打开 B 链接不会给他们返回链接......这是破坏者。
于 2012-09-27T12:00:33.913 回答