浏览器选项卡/窗口之间的JavaScript通信
在同一浏览器的标签页/窗口之间进行Javascript通信最可靠的方法是什么? 例如,当选项卡2开始播放audio时,选项卡1以某种方式知道这一点,并且可以暂停播放器。
我正在build立一个音乐播放器的网站…所以现在,如果你打开两个标签的网站,你可以开始在这两个音乐。 这显然是不好的,所以我试图find一个解决scheme。
有任何想法吗? 谢谢
您可以使用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>
对于更现代的解决scheme,请查看https://stackoverflow.com/a/12514384/270274
引用:
我坚持使用
localStorage
问题中提到的共享本地数据解决scheme。 这似乎是可靠性,性能和浏览器兼容性方面的最佳解决scheme。
localStorage
在所有现代浏览器中实现。当其他选项卡更改
localStorage
时,storage
事件触发。 这对通信目的来说非常方便。参考:
http://dev.w3.org/html5/webstorage/
http://dev.w3.org/html5/webstorage/#the-storage-event
我不认为你需要cookies。 每个文档的js代码都可以访问其他文档元素。 所以你可以直接使用它们来共享数据。 你的第一个窗口w1打开w2并保存参考
var w2 = window.open(...)
在w2中,您可以使用窗口的opener属性来访问w1。
您可以通过本地存储API执行此操作。 请注意,这仅适用于2个选项卡。 你不能把发送者和接收者放在同一个页面上:
在发件人页面上:
localStorage.setItem("someKey", "someValue");
在接收器页面上
$(document).ready(function () { window.addEventListener('storage', storageEventHandler, false); function storageEventHandler(evt) { alert("storage event called key: " + evt.key); } });
如果他们有一个孩子 – 父母关系,你可以在窗口之间进行通信(不论是否为选项卡)。
创build和更新一个子窗口:
<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
对象与产生它的parent
对象通信,所以你可以从任一窗口控制音乐播放器。
在这里看到它的行动: https : //jsbin.com/cokipotajo/edit?html,js,output
即使在HTML5之前,如果文档具有相同的来源,也支持在不同的JavaScript执行上下文之间进行通信。 如果没有,或者您没有其他Window
对象的引用,那么您可以使用HTML5引入的新postMessage API 。 我在这个计算器的答案阐述了两种方法。
窗口(w1)下方打开另一个窗口(w2)。 任何窗口都可以向/从另一个窗口发送/接收消息。 所以我们应该理想地validation这个消息来自我们打开的窗口(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", "*");
还有一种名为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"});
很明显,这是一种实用的技术,并且在所有的浏览器中都不被支持。
使用HTML5 localstoragefind了不同的方式,我创build了一个类似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)..ANYforms的闪存实例(ShockWave / activeX)