我能用一个HTML5应用程序控制两个浏览器窗口吗?

15

我希望我的HTML5应用程序可以绘制到两个不同的屏幕上。这意味着我需要有两个独立的浏览器窗口,一个在每个屏幕上。是否可能实现这一点?看起来我必须将相同的应用程序加载到两个窗口中,并以某种方式使窗口相互通信。我找不到如何完成此操作的示例。该怎么做?

额外的好处是:可能没有涉及服务器,只是从文件系统本地提供的应用程序。


可能是标签页或窗口之间的通信的重复问题。 - Michał Perłakowski
2个回答

18

不需要使用本地存储或(可怕的)Cookie 来实现混乱的轮询基础设施。 假设两个页面是从同一域名服务的,那么实现跨窗口通信就很容易,只要第一个窗口打开第二个窗口。

在你的主窗口中:点击这里查看JSFiddle演示这里查看辅助页面代码

var win2;
function openSecondaryWindow() {
   return win2 = window.open('win2.html','secondary','width=300,height=100');
}

$(function() {

    if (!openSecondaryWindow()) // Try to open the window.  This will likely be blocked by a popup blocker (unless you disable it).
        $(document.body) // If it is blocked, clicking a link usually allows the popup to be spawned.
        .prepend('<a href="#">Popup blocked.  Click here to open the secondary window.</a>')
        .click(function() { openSecondaryWindow(); return false; });

    $('#somelink').click(function() {
        if (win2) win2.doSomething(); // Obviously, you'll need to define doSomething in the second page
        else alert('The secondary window is not open.');
        return false;
    });
});

一旦主窗口打开了次要窗口,win2 将引用第二个页面的 window 对象 - 换句话说,该页面的全局作用域。这样,您就可以访问在第二个页面中定义的所有函数和变量。

因此,您可以通过函数调用传递数据。

win2.update({ key: 'value', ... });

从您的次要窗口中,可以通过opener属性调用主窗口中的函数,该属性将引用您的主窗口的window对象。(这在JSFiddle演示中有展示。)


更新:Intercom是一个使用本地存储实现窗口间广播消息的库。当数据发生变化时,本地存储会触发一个事件(onstorage),因此实际上不需要轮询。Intercom允许同一域名下的所有页面进行通信,而不管它们是如何打开的。


我一直在思考如何在打开和关闭窗口之间保持状态等问题,但你的解决方案对于Ned在他的帖子中提出的要求来说更好。很棒。 - Graham Conzett

0

这可能是你可以使用 websockets的东西,让每个窗口将其信息发送回应用程序,然后进行更新,但是这些在所有浏览器中都不受支持,事实上,我认为当前大多数构建都由于规范的安全问题而被删除了。

对于离线应用程序,如果它们在同一个域上,我假设它们会在本地使用本地存储甚至是cookie,然后使应用程序轮询对存储API所做的更改?

我最近一直在进行离线本地存储的一些实验,我能够在Chrome本地维护窗口之间的状态,在Firefox中,这种方法不起作用,但我相信在FF4 RC中已经解决了这个问题。

编辑2:

在两个文件中快速创建并证明了一个简单而粗糙的概念:

索引1:

<body>

<div id="result">x</div>

</body>
<script type="text/javascript">
var i = 0;

function update(){  
    setTimeout(function(){
        localStorage.setItem("bar", i);
        document.getElementById('result').innerHTML = "localstorage set to " + localStorage.getItem("bar");
        i++;
        console.log(i);
        update();          
    }, 2000);
}

update();

</script>

索引 2:

<body>

<div id="result">s</div>

</body>
<script type="text/javascript">

function update(){  
    setTimeout(function(){
        document.getElementById('result').innerHTML = localStorage.getItem("bar");    
        update();
    }, 1000);
}

update();

</script>

在Chrome本地打开它们的不同窗口中,第二个窗口将显示由第一个窗口中的循环设置的状态。在FireFox 4中仍然无法工作(昨天有一位Mozilla Dev向我发誓说离线本地存储现在可以使用,哦好吧)。你可能可以通过http://www.modernizr.com/在IE中使其工作,但我还没有测试过。


这是一个有趣的想法。虽然我没有涉及到服务器(我更新了问题)。 - Ned Batchelder
这是一个有趣的问题,我更新了我的答案并加入了一些更多的想法,也许使用本地存储甚至是 cookies 是解决问题的方法? - Graham Conzett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接