Связь Javascript между вкладками / окнами браузера
Какой самый надежный способ связи Javascript между вкладками / окнами одного и того же браузера? Например, когда Tab 2 начинает воспроизведение аудио, Tab 1 как-то знает об этом и может приостановить проигрыватель.
Я создаю сайт с помощью музыкального плеера... так что на данный момент, если вы откроете две вкладки на сайте, вы можете запустить музыку на обеих. Это явно плохо, поэтому я пытаюсь найти решение.
Есть идеи? Спасибо
10 ответов
Это старый ответ, я предлагаю использовать современную версию, описанную здесь:
Javascript; связь между вкладками / окнами с одинаковым происхождением
Вы можете общаться между окнами браузера (и вкладками тоже), используя куки.
Вот пример отправителя и получателя:
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>
Для более современного решения проверьте /questions/23317445/javascript-svyaz-mezhdu-vkladkami-oknami-s-odinakovyim-proishozhdeniem/23317451#23317451
Цитата:
Я придерживаюсь общего локального решения данных, упомянутого в вопросе, используя
localStorage
, Кажется, это лучшее решение с точки зрения надежности, производительности и совместимости с браузерами.
localStorage
реализовано во всех современных браузерах.
storage
событие запускается, когда другие вкладки вносят изменения вlocalStorage
, Это очень удобно для общения.Ссылка:
http://dev.w3.org/html5/webstorage/
http://dev.w3.org/html5/webstorage/
Я не думаю, что вам нужны куки. Код js каждого документа может получить доступ к другим элементам документа. Таким образом, вы можете использовать их напрямую для обмена данными. Ваше первое окно w1 открывает w2 и сохраняет ссылку
var w2 = window.open(...)
В w2 вы можете получить доступ к w1 используя свойство opener окна.
Существует также экспериментальная технология под названием 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). Любое окно может отправлять / получать сообщения в / из другого окна. Поэтому в идеале мы должны убедиться, что сообщение пришло из окна (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", "*");
Связь между различными контекстами выполнения JavaScript поддерживалась еще до HTML5, если документы были одного происхождения. Если нет или у вас нет ссылки на другой Window
объект, тогда вы можете использовать новый API postMessage, представленный в HTML5. Я подробно описал оба подхода в этом ответе stackru.
Вы можете общаться между окнами (с вкладками или нет), если у них есть дочерние и родительские отношения.
Создайте и обновите дочернее окно:
<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 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});
};
он будет отправлять сообщения на все остальные страницы, но не на текущую.
Редактировать: с помощью Flash вы можете общаться между любыми окнами, ЛЮБЫМ браузером (да, от FF до IE во время выполнения) ...ЛИ форма экземпляра flash (ShockWave/activeX)