Javascript; communication entre onglets / fenêtres de même origine [dupliquer]
cette question a déjà une réponse ici:
- Communication entre onglets ou windows 8 réponses
j'ai deux fenêtres: fenêtre A et fenêtre B.
- les fenêtres A et B ont le même domaine
- fenêtre A et fenêtre B n'a pas toute la fenêtre parent.
Questions:
- est-il possible pour la fenêtre A d'obtenir une référence de la fenêtre B?
- Quelle est la façon la plus élégante de rendre la fenêtre a notifier quelque chose à la fenêtre B?
(y compris les nouvelles spécifications HTML5)
deux façons dont je suis conscient de faire ceci:
- messagerie par serveur: où fenêtre B regulary demande au serveur si window A A notifié quelque chose
- messagerie par données locales (HTML5): quand la fenêtre a veut notifier quelque chose elle change les données locales, la fenêtre B vérifie régulièrement les données locales pour tout changement.
mais les deux voies ne sont pas si élégantes.
Par exemple, il serait bien d'obtenir une référence de la fenêtre B et d'utiliser la fenêtre.postMessage () (HTML5)
le but ultime est de faire quelque chose comme facebook où si vous ouvrez 4 facebook onglets et de chat dans l'un onglet, le chat est à jour facebook onglet, qui est soignée!
7 réponses
Je m'en tiens à la solution de données locales partagées mentionnée dans la question en utilisant localStorage
. Elle semble être la meilleure solution en termes de fiabilité, de performance et de compatibilité avec les navigateurs.
localStorage
est implémenté dans tous les navigateurs modernes.
l'événement storage
se déclenche lorsque autre tabs apporte des changements à localStorage
. C'est assez pratique pour des fins de communication.
Les références se trouvent ici:
Webstorage
Webstorage - événement de stockage
la norme BroadcastChannel permet de le faire. Actuellement, il est mis en œuvre dans Firefox et Chrome ( caniuse , mdn ):
// tab 1
var ch = new BroadcastChannel('test');
ch.postMessage('some data');
// tab 2
var ch = new BroadcastChannel('test');
ch.addEventListener('message', function (e) {
console.log('Message:', e.data);
});
SharedWorker est la spécification WHATWG/ HTML5 pour un processus commun qui peut communiquer entre les onglets.
vous avez dit votre:
Ulimate but est de faire quelque chose comme facebook où si vous ouvrez 4 onglets facebook, et chat dans un onglet, le chat est actualiser sur chaque onglet facebook, qui est soigné!
qui devrait se produire comme un sous-produit de votre conception, les vues questionner le modèle (probablement le serveur) pour les mises à jour du chat, plutôt que de votre avoir à concevoir dans la communication de cross-view. À moins que vous ayez affaire à transférer d'énormes quantités de données, Pourquoi s'en inquiéter? On dirait que ça va compliquer les choses sans grand gain.
il y a des années, j'ai découvert que si je faisais window.open
en utilisant le nom d'une fenêtre existante et une URL vierge, j'obtenais une référence à la fenêtre existante (ce comportement est même documenté sur MDC et un commentaire sur le MSDN docs suggère qu'il fonctionne dans IE aussi). Mais c'était il y a des années, je ne sais pas comment universel le support pour cela est dans le monde d'aujourd'hui, et bien sûr vous n'aurez pas de nom de fenêtre à chercher à moins que toutes vos fenêtres incluent un nommé iframe
pour la communication, nommé uniquement via le code côté serveur, et ensuite communiqué aux autres fenêtres au moyen de code côté serveur... (Pensée effrayante: cela pourrait en fait être faisable. Enregistrez les noms de fenêtre "courants" relatifs à un compte connecté dans une table, donnez la liste à toute nouvelle fenêtre créée qui se connecte à ce compte, supprimez les anciens inactifs entrée. Mais si la liste est légèrement périmée, vous ouvrirez de nouvelles fenêtres lorsque vous en chercherez d'autres... Et je parie que la prise en charge est difficile d'un navigateur à l'autre.)
outre le prochain SharedWorker , vous pouvez également utiliser Cross-document messaging , qui est beaucoup plus largement pris en charge . Dans ce scénario, il doit y avoir une fenêtre principale qui est responsable d'ouvrir toutes les autres fenêtres avec window.open
. Les fenêtres enfant peuvent alors utiliser postMessage sur leur window.opener
.
si l'utilisation de flash est une option pour vous, Il ya aussi le beaucoup plus ancien connexion locale virtuellement supporté sur n'importe quel client avec flash installé ( exemple de code ).
autres méthodes de repli:
postMessage plugin pour jQuery avec window.emplacement.href retombée pour les navigateurs plus anciens
solution basée sur les cookies pour la communication non instantanée
AFAIK, il est impossible de communiquer à travers windows s'ils n'ont pas le même parent.
S'ils ont tous les deux été ouverts à partir d'une fenêtre parent, vous devriez être en mesure de mettre la main sur les références variables du parent.
dans le parent, ouvrez les fenêtres comme ceci:
childA = window.open(...);
childB = window.open(...)
dans Enfanta, l'accès childB comme ceci:
childB = window.opener.childA
j'ai une façon soignée de faire un tel tour, mais avec des restrictions: vous devez autoriser les popups pour votre domaine et vous obtiendrez une page toujours ouverte (comme onglet ou comme popup) qui mettra en œuvre les communications entre windows.
voici un exemple: http://test.gwpanel.org/test/page_one.html (rafraîchir la page après avoir activé les popups pour le domaine)
la caractéristique principale de ce trick-popup est ouvert avec le fragment d'url ' # ' dans la fin, ce navigateur force à ne pas changer l'emplacement de la fenêtre et stocker toutes les données. Et de la fenêtre.postMessage faire le reste.