ejemplo - set local storage javascript
Javascript; comunicaciĆ³n entre pestaƱas/ventanas con el mismo origen (7)
Esta pregunta ya tiene una respuesta aquí:
- Comunicación entre pestañas o ventanas 8 respuestas
Tengo dos ventanas: ventana A y ventana B.
- la ventana A y la ventana B tienen el mismo dominio
- la ventana A y la ventana B no tienen ventana principal.
Preguntas:
- ¿Es posible que la ventana A obtenga una referencia de la ventana B?
- ¿Cuál es la manera más elegante de hacer que la ventana A notifique algo a la ventana B?
(incluidas las nuevas especificaciones HTML5)
Dos maneras en que soy consciente de hacer esto:
- mensajes por servidor: donde la ventana B regulary pregunta al servidor si la ventana A ha notificado algo
- mensajería por datos locales (HTML5): cuando la ventana A desea notificar a algo que cambia los datos locales, la ventana B regulary verifica los datos locales para detectar cualquier cambio.
Pero las dos formas no son tan elegantes.
Por ejemplo, sería bueno obtener una referencia de la ventana B y usar window.postMessage () (HTML5)
El objetivo principal es hacer algo como Facebook, donde si abres 4 pestañas de Facebook y chateas en una sola pestaña, el chat estará actualizado en todas las pestañas de Facebook, ¡lo cual es genial!
AFAIK, es imposible comunicarse a través de las ventanas si no tienen el mismo padre.
Si ambos han sido abiertos desde una ventana principal, debería poder obtener las referencias variables de los padres.
En el padre, abra las ventanas de esta manera:
childA = window.open(...);
childB = window.open(...)
en ChildA, acceda a childB de esta manera:
childB = window.opener.childA
Además del próximo caniuse.com/sharedworkers , también puede usar mensajes cruzados , que son mucho más supported . En este escenario, debe haber una ventana principal que sea responsable de abrir todas las demás ventanas con window.open
. Las ventanas secundarias pueden usar postMessage en su window.opener
.
Si el uso de flash es una opción para usted, también existe una LocalConnection mucho más antigua que es virtualmente compatible con cualquier cliente con flash instalado ( código de ejemplo ).
Otros métodos de respaldo:
plugin postMessage para jQuery con window.location.href de respaldo para navegadores antiguos
solución basada en cookies para comunicación no instantánea
Dijiste tu:
El objetivo principal es hacer algo como Facebook, donde si abres 4 pestañas de Facebook y chateas en una sola pestaña, el chat se actualiza en cada pestaña de Facebook, ¡que está perfecto!
Eso debería suceder como un subproducto de su diseño, las vistas que consultan el modelo (probablemente el servidor) para las actualizaciones del chat, en lugar de tener que diseñar en la comunicación de vista cruzada. A menos que esté tratando de transferir grandes cantidades de datos, ¿por qué preocuparse? Parece que complicará las cosas sin una gran ganancia.
Hace años descubrí que si hacía window.open
usando el nombre de una ventana existente y una URL en blanco, obtuve una referencia a la ventana existente (este comportamiento incluso está documentado en MDC y un comentario en los documentos de MSDN sugiere que funciona en IE también). Pero eso fue hace años, no sé cuán universal es la compatibilidad en el mundo de hoy, y por supuesto no tendrá un nombre de ventana para buscar a menos que todas sus ventanas incluyan un iframe
nombrado para comunicación, nombrado de manera única a través del código del lado del servidor, y luego se comunicó a las otras ventanas por medio del código del lado del servidor ... (Pensamiento aterrador: Eso podría ser factible. Almacene los nombres de ventanas "actuales" relacionados con una cuenta registrada en una tabla , dé la lista a cualquier nueva ventana creada que inicie sesión en esa cuenta, elimine las entradas antiguas inactivas. Pero si la lista está un poco desactualizada, abrirá nuevas ventanas cuando busque otras ... Y apuesto a que el soporte es dudoso desde navegador al navegador)
El estándar BroadcastChannel permite hacer esto. En este momento está implementado en Firefox y 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 es la especificación WHATWG / HTML5 para un proceso común que puede comunicarse entre pestañas.
Tengo una forma clara de hacer ese truco, pero con restricciones: debe permitir ventanas emergentes para su dominio y siempre tendrá una página abierta (como una pestaña o una ventana emergente) que implementará las comunicaciones entre ventanas.
Aquí hay un ejemplo: http://test.gwpanel.org/test/page_one.html (página de actualización después de habilitar las ventanas emergentes para el dominio)
La característica principal de este truco - popup se está abriendo con el fragmento de url ''#'' al final, este navegador de fuerza para no cambiar la ubicación de la ventana y almacenar todos los datos. Y window.postMessage hace el resto.
Me estoy apegando a la solución compartida de datos locales mencionada en la pregunta usando localStorage
. Parece ser la mejor solución en términos de fiabilidad, rendimiento y compatibilidad del navegador.
localStorage
se implementa en todos los navegadores modernos.
El evento de storage
se dispara cuando otras pestañas localStorage
cambios en localStorage
. Esto es bastante útil para fines de comunicación.
Las referencias se pueden encontrar aquí:
Webstorage
Webstorage - evento de almacenamiento