Let iframes to communicate

The postMessage method is a mean to a page to exchange data with an iframe or iframes to communicate with each other.

Using DOM

But this is not the simplest. An iframe can access the content of the page that contains it with the DOM through the parent property of window. And conversely a page accesses an iframe by its identifier and the window object, and depending on the browser by the contentWindows or contentDocument property.

<iframe id="if1" src="iframe-demo.html"></iframe>

var if = document.getElementById("if1");
var fc = (if1.contentWindow || if1.contentDocument);

Below the iframe-demo.html page that is included in an iframe on this page ...

It contains a text and an image.

You may through the DOM replace that image with another...

Source code:

<script>
function replaceImg(img) {
var if1 = document.getElementById("if1");
var fc = (if1.contentWindow || if1.contentDocument);
var img1 = fc.document.getElementById("idemo");
img1.src=img;
}
</script>
<p><input type="button" value="Replace" onclick="replaceImg('images/angry-birds.jpg')" /></p>

Source code in iframe-demo.html

<img id="idemo" src="/html5/images/freeciv.jpg">

iFrame and parent document

The page loaded in the iframe can also communicate through the DOM. Click the button in the iframe below to send its data to this page.

Field to fill

Source code in this page:

<iframe id="if2" src="iframe-demo2.html" width="320" height="150"></iframe>
<fieldset><legend>Field to fill</legend><div id="storage"></div></fieldset>

Source code in iframe-demo2.html:

<script>
function sendDataToContainer() {
var storage = parent.document.getElementById("storage");
var data = document.getElementById("data");
storage.innerHTML = data.innerHTML;
}
</script>
<p id="data">Text sent...</p>
<p><input type="button" value="Replace" onclick="sendDataToContainer()" /></p>

postMessage

A standard API has been defined by the W3C to let independent web pages to communicate. It adds postPaster method to the window object to send data, and the event "message" to receive them. Note that postMaster is not associated to the current window, but to the window that receive the data instead.

It is necessary to specify the domain as an argument of the method. Xul.fr is used in the example to work on this site. In your application, you will use your own domain.

In this demo, we display in two iframes, the first holds the iframe-demo3.html page, and the second the iframe-demo4.html page. We want to exchange data (a simple text in this demo) between the main page and these iframes.

Click a button in an iframe to transfer the text it contains, to this page.

Received from iframes
Send to iframe
Text to send to an iframe.

Source in the main page (without presentation code):

<iframe id="if3" src="iframe-demo3.html" width="320" height="200"></iframe>
<iframe id="if4" src="iframe-demo4.html" width="320" height="200"></iframe>

<div id="storage3"></div>
<script>
function getMessage(e) {
if(e.origin !== 'http://www.xul.fr') return;
document.getElementById("storage3").innerHTML=e.data;
}
window.addEventListener("message", getMessage, false);
function sendMessage(id) {
var data = document.getElementById("data").innerHTML;
var ifr = document.getElementById(id);
var target = (ifr.contentWindow || ifr.contentDocument);
target.postMessage(data, 'http://www.xul.fr');
}
</script> <p id="data">Text to send to an iframe.</p>

<input type="button" value="Send to left" onClick="sendMessage('if3')" />
<input type="button" value="Send to right" onClick="sendMessage('if4')" />

Replace http://www.xul.fr by your own domain.

Source in the page loaded in an iframe:

<script>
<script>
function getMessage(e) {
if(e.origin !== 'http://www.xul.fr') return;
document.getElementById("storage").innerHTML=e.data;
}
window.addEventListener("message", getMessage, false);
function sendMessage() {
var data = document.getElementById("data").innerHTML;
window.parent.postMessage(data, 'http://www.xul.fr');
}
</script>

<p id="data">Data from iframe-demo3.html...</p>
<div id="storage"></div>
<input type="button" value="Send data" onClick="sendMessage()" />

Communicating directly between iframes is also possible by combining window.parent with target as defined above.

In conclusion, the postMessage method is a more dynamic alternative to the single DOM, better suited if you load multiple pages in one iframe, but not always easier and it still requires the use of the DOM.

WebMessaging spécification by W3C.

© March 27, 2015 Xul.fr