如何在localStorage中维护浏览器Tab对象?

时间:2018-04-11 08:53:22

标签: javascript jsp

我正在开发一个Web应用程序。

在此,我需要在主页面的不同浏览器标签中打开多个页面,如果主页面关闭,则所有其他打开的浏览器标签需要关闭或单击Close Tab按钮。

我使用Array完成了此操作,但当主页刷新时,Array会自动重置。

示例代码: -

JSP

<a4j:commandButton value="Test1" onclick="return newTab('test1.jsp');"/>
<a4j:commandButton value="Test2" onclick="return newTab('test2.jsp');"/>
<a4j:commandButton value="Test3" onclick="return newTab('test3.jsp');"/> 

<a4j:commandButton value="Close Tab" onclick="closeTabs();"/> 

的JavaScript

  var windowObject = new Array();
  function newTab(mypage)
     {
        var newwin=window.open(mypage);
        windowObject.push(newwin);
        return false;
     }

  function closeTabs()
     {
        for (i = 0; i < windowObject.length; i++) 
            {
              windowObject[i].close();
            }
     }

帮我解决这个问题。

2 个答案:

答案 0 :(得分:1)

TLDR; 从理论上讲,它无法完成。实际上,你总能找到解决办法。

为什么我们不能存储对窗口的引用

刷新页面时,您无法将实际的引用保留到窗口(即具有关联方法的对象),因为您存储它的唯一地方是Cookie或localStorage。但这些只允许您存储数据的字符串表示。因此,重新加载页面后,您将无法再使用这些window元素。 (即使你可以存储实际的对象,它们也是无用的副本 - 不是完整的circular Objects,例如window

解决方法

我发现你的问题很有趣,所以我尝试了这个概念证明:

两种类型的网页

页面将能够打开从属页面。只要你不刷新它,它也可以关闭它们。但如果你这样做,你就需要找到一种方法给他们留言,让他们知道他们应该被关闭。

在冰箱上留言

在这里,我们的冰箱将是localStorage。当 slave 页面打开时,它会向冰箱添加便利贴,给出其ID和状态。可以通过 master 页面访问和修改此post-it。每个 slave 会定期检查其关联的post-it,并查看它是否应自行关闭。

您可以创建的算法

这个伪代码以简单的方式展示了你如何做到这一点。

母版页脚本

// If the page was simply refreshed, we want to cancel our
// post-it modifications before they take effect
when (window_is_loaded) :
    cancel_previous_postit_modifications()

when (open_slaves_button_is_clicked) :
    open_slaves()

// Here, we know we can close the slaves
when (close_slaves_button_is_clicked) :
    tell_slaves_to_close()

// Here, we don't know whether this is a refresh or not,
// So we tell them to wait, and close if they don't here back from us
when (window_is_being_unloaded) :
    tell_slaves_to_close_after_delay()

从属页面脚本

when (window_is_loaded) :
    create_postit_note()

when (window_is_being_unloaded) :
    remove_postit()

every (X milliseconds) :
    if (status_on_postit_is('willBeClosed')) :
        change_status_to('shouldBeClosed')
    else if (status_on_postit_is('shouldBeClosed')) :
        close_window()

测试代码

为了检查这是否可行,我创建了一个测试项目:

完整代码: https://github.com/blex41/slave-windows

现场演示: Here

答案 1 :(得分:0)

如果您关闭/刷新主选项卡,那么您将丢失阵列数据,并且您将无法关闭已打开的选项卡。

解决此问题的可能解决方案是,将标签信息保存在本地存储中,以便每次调用close(),然后从本地存储中获取选项卡名称迭代它并关闭打开的选项卡。

local-storage仅支持存储字符串类型变量,您可以在下面的问题中看到如何在localstorage中存储和检索数组。 How do I store an array in localStorage?