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í!
Oldest comments (3)
Isso é muito útil. Não sabia que podia haver comunicação entre eles. Isto será bem útil para mim. Obrigado por compartilhar
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