Introdução
Iframes! Quando ouvimos falar sobre esse elemento parece que estamos voltando no tempo. Como naquelas páginas bonitas em que o menu chamava cada parte do site dentro de um desses elementos. Mas os iframes ainda existem, sempre vão existir, e servem para muitos propósitos.
Há algum tempo eu tive que fazer um chat que iria ser embedado no site dos nossos clientes e então surgiu a primeira questão:
Como incluir um site dentro de outro?
Fui buscar como outras empresas faziam e óbvio que TODOS usavam iframe. É necessário isolar o escopo, não pode haver vazamento de css/html e muito menos de javascript, algo que o iframe faz muito bem.
Problema
Ao inserir o chat em um site, temos dois estados:
- Aberto
- Fechado
Um iframe não pode mudar seu tamanho, não temos acesso ao document
dentro dele. Para isso precisamos avisar o lado de fora do iframe.
window.postMessage
Foi então que descobri o window.postMessage
(documentação) que permite enviar eventos para uma window (target) diferente. Assim posso deixar algum listener na window no qual incluo o iframe e enviar um evento falando qual o tamanho que o iframe precisa ter.
Para emitir um evento do iframe é tão simples quanto:
window.parent.postMessage('mensagem vinda do iframe', '*')
- window.parent: window de destino do evento, a window do iframe contém a propriedade parent, que é a referência para a página em que está incluso
- postMessage: o método em si, recebe dois parâmetros: o dado que será enviado (nesse exemplo enviei uma string simples) e a url de destino (passando * é aceito qualquer origem)
Recebendo o evento
Do lado parent, ou seja, o que recebe o evento, temos que ficar escutando o evento message
da window, por exemplo:
// window escutando o evento `message` que o postMessage envia
window.addEventListener('message', function(e){
// para ter acesso ao dado temos que acessar a propriedade data
console.log(e.data)
})
Enviando dado para o iframe
Para enviar o dado para o iframe, primeiro precisamos recuperar o elemento:
const meuIframe = document.getElementById('meuiframe')
Com o elemento podemos chamar o postMessage da mesma forma que fizemos dentro dele, chamando direto a window do mesmo:
meuIframe.contentWindow.postMessage('mensagem pro iframe', '*')
Conclusão
Com o postMessage fica simples e seguro, se usar o segundo parâmetro como filtro de destino para se comunicar com iframes.
Fiz dois exemplos simples do uso, um chat entre páginas e um
alterando o tamanho do iframe.
Qualquer dúvida ou sugestão comenta aí!
Top comments (3)
Ajudou demais. Obrigado.
Conhecia muito superficialmente essa comunicação, mas com seu exemplo, simples e direto foi perfeito para o projeto em que estou trabalhando.
o/
Que bom! Fico feliz em ter ajudo, qlqr dúvida comenta aí ou nos repôs,abraço
Isso é muito útil. Não sabia que podia haver comunicação entre eles. Isto será bem útil para mim. Obrigado por compartilhar