浏览器标签/窗口之间的Javascript通信[重复]

2020/11/13 04:42 · javascript ·  · 0评论

在同一浏览器的选项卡/窗口之间进行JavaScript通信的最可靠方法是什么?例如,当标签2开始音频播放,标签1莫名其妙地知道这一点,可以暂停的球员。

我正在建立一个带有音乐播放器的网站...因此,如果您现在打开该网站的两个标签,则可以同时在两者上播放音乐。这显然是不好的,所以我正在尝试寻找解决方案。

有任何想法吗?谢谢

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

Javascript; 具有相同来源的选项卡/窗口之间的通信


您可以使用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>

For a more modern solution check out https://stackoverflow.com/a/12514384/270274

Quote:

I'm sticking to the shared local data solution mentioned in the question using localStorage. It seems to be the best solution in terms of reliability, performance, and browser compatibility.

localStorage is implemented in all modern browsers.

The storage event fires when other tabs makes changes to localStorage. This is quite handy for communication purposes.

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

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

var w2 = window.open(...) 

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

还有一种称为实验性的技术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"});

显然,这是一种体验技术,尚不支持所有浏览器。

您可以通过本地存储API执行此操作。请注意,这仅在2个标签之间有效。您不能将发送方和接收方都放在同一页面上:

在发件人页面上:

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

在接收者页面上

    $(document).ready(function () {

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

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

在窗口(w1)下方打开另一个窗口(w2)。任何窗口都可以向另一个窗口发送消息或从另一个窗口接收消息。因此,理想情况下,我们应该验证消息是否源自我们打开的window(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", "*");

如果窗口之间有子母关系,则可以在窗口之间进行通信(是否选中)。

创建和更新子窗口:

<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

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

使用HTML5本地存储找到了不同的方式,我创建了一个带有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});
};

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

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

本文地址:http://javascript.askforanswer.com/liulanqibiaoqian-chuangkouzhijiandejavascripttongxinzhongfu.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!