Pergunta

Essa pergunta já tem resposta aqui:

Eu tenho duas janelas:janela A e janela B.

  • janela A e janela B têm o mesmo domínio
  • a janela A e a janela B não possuem nenhuma janela pai.

Questões:

  1. É possível que a janela A obtenha uma referência da janela B?
  2. qual é a maneira mais elegante de fazer a janela A notificar algo para a janela B?
    (incluindo novas especificações HTML5)

Estou ciente de duas maneiras de fazer isso:

  • mensagens por servidor:onde a janela B pergunta regularmente ao servidor se a janela A notificou algo
  • mensagens por dados locais (HTML5):quando a janela A deseja notificar algo que altera os dados locais, a janela B verifica regularmente os dados locais em busca de quaisquer alterações.

Mas as duas formas não são tão elegantes.
Por exemplo, seria bom obter uma referência da janela B e usar window.postMessage() (HTML5)

O objetivo final é fazer algo parecido com o Facebook, onde se você abrir 4 abas do Facebook e conversar em uma aba, o bate-papo será atualizado em todas as abas do Facebook, o que é legal!

Foi útil?

Solução

Estou mantendo a solução de dados local compartilhada mencionada na pergunta usando localStorage. Parece ser a melhor solução em termos de confiabilidade, desempenho e compatibilidade do navegador.

localStorage é implementado em todos os navegadores modernos.

o storage Evento dispara quando outro guias fazem alterações para localStorage. Isso é bastante útil para fins de comunicação.

As referências podem ser encontradas aqui:
Armazenamento web
WebStorage - Evento de armazenamento

Outras dicas

O padrão BroadcastChannel permite fazer isso. No momento, ele é implementado no Firefox e Chrome (eu posso usar, 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);
});

O SharedWorker é a especificação WhatWG/ HTML5 para um processo comum que pode se comunicar entre as guias.

Você disse o seu:

O objetivo Utlimate é fazer algo como o Facebook, onde você abrir 4 guias no Facebook e conversar em uma guia, o bate -papo está atualizado em todas as guias do Facebook, o que é legal!

Isso deve acontecer como um subproduto do seu design, as visualizações consultar o modelo (provavelmente o servidor) para atualizações no bate-papo, em vez de você ter que projetar na comunicação de visão cruzada. A menos que você esteja lidando com a transferência de grandes quantidades de dados, por que se preocupar com isso? Parece que complicará as coisas sem um grande ganho.

Anos atrás eu descobri que se eu fiz window.open Usando o nome de uma janela existente e um URL em branco, recebi uma referência à janela existente (esse comportamento é uniforme Documentado no MDC e um comentário sobre O MSDN Docs sugere que funciona no IE também). Mas isso foi anos atrás, não sei o quão universal o apoio é no mundo de hoje e, é claro, você não terá um nome de janela para procurar, a menos que todas as suas janelas incluam um nomeado iframe Para a comunicação, nomeado exclusivamente via código do lado do servidor, e depois se comunicou às outras janelas por meio de código do lado do servidor ... (pensamento assustador: isso pode ser realmente viável. Armazene os nomes de janelas "atuais" relacionados a um logado- Em conta em uma tabela, dê a lista a qualquer nova janela criada que faça login nessa conta, abate as entradas inativas antigas. Mas se a lista estiver um pouco desatualizada, você abrirá novas janelas ao procurar outras pessoas ... e eu O suporte da BET é duvidoso do navegador para o navegador.)

Além do próximo SharedWorker, você também pode usar Mensagens de documentos cruzados, que é muito mais amplamente suportado. Nesse cenário, deve haver uma janela principal responsável por abrir todas as outras janelas com window.open. As janelas infantis podem então usar postar mensagem em seus window.opener.

Se usar o flash é uma opção para você, também há o muito mais antigo LocalConnection Praticamente suportado em qualquer cliente com flash instalado (código de exemplo).

Outros métodos de fallbacks:
plug -in de pós -maquiagem para jQuery com window.location.href Fallback para navegadores mais antigos
Solução baseada em biscoitos para comunicação não instantânea

AFAIK, é impossível comunicar-se entre janelas se elas não tiverem o mesmo pai.

Se ambos foram abertos a partir de uma janela pai, você poderá obter as referências de variáveis ​​do pai.

No pai, abra as janelas assim:

childA = window.open(...);
childB = window.open(...)

em ChildA, acesse childB assim:

childB = window.opener.childA

Eu tenho uma maneira interessante de fazer esse truque, mas com restrições: você deve permitir pop -ups para o seu domínio e você receberá uma página sempre aberta (como guia ou como pop -up), que implementará as comunicações entre o Windows.

Aqui está um exemplo:http://test.gwpanel.org/test/page_one.html(Página de atualização após ativar pop -ups para domínio)

O principal recurso desse truque - o pop -up está sendo aberto com o URL Fragment '#' no final, este navegador de força para não alterar a localização da janela e armazenar todos os dados. E Window.PostMessage Faça o resto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top