浏览器标签/窗口之间的Javascript通信

时间:2010-11-02 15:36:26

标签: javascript browser

在同一浏览器的标签/窗口之间进行Javascript通信的最可靠方法是什么?例如,当Tab 2开始播放音频时,Tab 1会以某种方式知道这一点并暂停播放器。

我正在建立一个带有音乐播放器的网站...所以,如果你打开两个标签到网站,你可以在两者上开始播放音乐。 这显然很糟糕,所以我试图找到一个解决方案。

有什么想法吗? 谢谢

10 个答案:

答案 0 :(得分:143)

要获得更现代化的解决方案,请查看https://stackoverflow.com/a/12514384/270274

引用:

  

我坚持使用localStorage在问题中提到的共享本地数据解决方案。它似乎是可靠性,性能和浏览器兼容性方面的最佳解决方案。

     

localStorage已在所有现代浏览器中实施。

     

其他标签对storage进行更改时会触发localStorage事件。这对于沟通来说非常方便。

     

参考:
  http://dev.w3.org/html5/webstorage/
  http://dev.w3.org/html5/webstorage/#the-storage-event

答案 1 :(得分:91)

这是一个陈旧的答案,我建议使用这里描述的现代版本:

Javascript; communication between tabs/windows with same origin


您可以使用Cookie在浏览器窗口(以及标签)之间进行通信。

以下是发件人和收件人的示例:

sender.html

<h1>Sender</h1>

<p>Type into the text box below and watch the text 
   appear automatically in the receiver.</p>

<form name="sender">
<input type="text" name="message" size="30" value="">
<input type="reset" value="Clean">
</form>

<script type="text/javascript"><!--
function setCookie(value) {
    document.cookie = "cookie-msg-test=" + value + "; path=/";
    return true;
}
function updateMessage() {
    var t = document.forms['sender'].elements['message'];
    setCookie(t.value);
    setTimeout(updateMessage, 100);
}
updateMessage();
//--></script>

receiver.html:

<h1>Receiver</h1>

<p>Watch the text appear in the text box below as you type it in the sender.</p>

<form name="receiver">
<input type="text" name="message" size="30" value="" readonly disabled>
</form>

<script type="text/javascript"><!--
function getCookie() {
    var cname = "cookie-msg-test=";
    var ca = document.cookie.split(';');
    for (var i=0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(cname) == 0) {
            return c.substring(cname.length, c.length);
        }
    }
    return null;
}
function updateMessage() {
    var text = getCookie();
    document.forms['receiver'].elements['message'].value = text;
    setTimeout(updateMessage, 100);
}
updateMessage();
//--></script>

答案 2 :(得分:14)

我认为你不需要cookies。每个文档的js代码都可以访问其他文档元素。因此,您可以直接使用它们来共享数据。 您的第一个窗口w1打开w2并保存参考

var w2 = window.open(...) 

在w2中,您可以使用window的opener属性访问w1。

答案 3 :(得分:11)

您可以通过本地存储API执行此操作。请注意,这仅适用于2个选项卡。您不能将发件人和收件人放在同一页面上:

在发件人页面上:

localStorage.setItem("someKey", "someValue");

在接收者页面上

    $(document).ready(function () {

        window.addEventListener('storage', storageEventHandler, false);

        function storageEventHandler(evt) {
            alert("storage event called key: " + evt.key);
        }
    });

答案 4 :(得分:10)

还有一种称为Broadcast Channel API的实验性技术,专门用于具有相同来源的不同浏览器上下文之间的通信。您可以在不引用消息的情况下向其他浏览器上下文发送消息并从中接收消息:

var channel = new BroadcastChannel("foo");
channel.onmessage = function( e ) {
  // Process messages from other contexts.
};
// Send message to other listening contexts.
channel.postMessage({ value: 42, type: "bar"});

显然,这是一项经验技术,目前尚未得到所有浏览器的支持。

答案 5 :(得分:9)

如果窗口之间存在子父关系,则可以在窗口之间进行通信(选项卡式还是非选项卡式)。

创建和更新子窗口:

<html>
<head>
<title>Cross window test script</title>
<script>
var i = 0;
function open_and_run() {
    var w2 = window.open("", "winCounter"); 
    var myVar=setInterval(function(){myTimer(w2)},1000);
}

function myTimer(w2) {
    i++;
    w2.document.body.innerHTML="<center><h1>" + i + "</h1><p></center>";
}
</script>
</head>
<body>
Click to open a new window 
<button onclick="open_and_run();">Test This!</button>    
</body>
</html>

子窗口可以使用parent对象与产生它的父级进行通信,因此您可以从任一窗口控制音乐播放器。

在此处查看此行动:https://jsbin.com/cokipotajo/edit?html,js,output

答案 6 :(得分:9)

窗口下方(w1)打开另一个窗口(w2)。任何窗口都可以向/从另一个窗口发送/接收消息。因此,我们应该理想地验证消息来自我们打开的窗口(w2)。

在w1

var w2 = window.open("abc.do");
window.addEventListener("message", function(event){
    console.log(event.data);
});

在w2(abc.do)

window.opener.postMessage("Hi! I'm w2", "*");

答案 7 :(得分:8)

如果文档来源相同,甚至在HTML5之前就支持在不同的JavaScript执行上下文之间进行通信。如果没有,或者您没有引用其他Window对象,则可以使用HTML5引入的新 postMessage API 。我在这个stackoverflow answer中详细阐述了两种方法。

答案 8 :(得分:1)

使用HTML5 localstorage找到不同的方式,我创建了一个包含API等事件的库:

sysend.on('foo', function(message) {
    console.log(message);
});
var input = document.getElementsByTagName('input')[0];
document.getElementsByTagName('button')[0].onclick = function() {
    sysend.broadcast('foo', {message: input.value});
};

它会向所有其他页面发送消息,但不会向当前页面发送消息。

答案 9 :(得分:-2)

编辑: 使用Flash,您可以在任何窗口,任何浏览器之间进行通信(是的,在运行时从FF到IE)..某种形式的flash实例(ShockWave / activeX)