Channel Messaging API - Sending data from parent window to iframe window:
You can use the Channel Messaging API to communicate between parent and child iframe windows or between two iframes as well. The procedure might seem a bit complicated but let me show you the code below.
Simple example of the Channel Messaging API
The process might sound a bit complicated but here's the outline of how to get Channel Messaging API to work for you. The API works in tandem with the Post Message API to send and receive messages.
- A message Channel is created using the MessageChannel() constructor.
- Keep a copy of the
port1
from the channel object returned from the above constructor. This will be used to receive messages from the iframe. - Send out the
port2
from the parent to the iframe. The iframe saves it and uses it to receive messages.
Parent Window
<!-- index.html -->
<p id="message-output">Message not yet sent</p>
<form id="channel-form">
<label for="message">
Send a message to the iframe
<input id="message" type="text" placeholder="Enter message here" />
</label>
<button type="submit">Send Message</button>
</form>
<iframe src="page2.html" width="480" height="320"></iframe>
</body>
<!-- Get the parent's javascript -->
<script src="./parent.js"></script>
// parent.js
/* Step 1 : Message channel is created */
var channel = new MessageChannel();
var port1 = channel.port1;
/* Step 2: Using the copy of port1 */
// Hooking up onMessage handler to receive messages from iframe, listening to mesages on port1.
port1.onmessage = onMessage;
// Message handler for port1
function onMessage(e) {
output.innerHTML = e.data;
}
/* Step 3: Sending out the port2 on load */
// Wait for the iframe to load to send the port2.
iframe.addEventListener("load", onLoad);
function onLoad() {
// Transfer port2 to the iframe
iframe.contentWindow.postMessage("init", "*", [channel.port2]);
}
// Listen for button clicks
$form.addEventListener("submit", onSubmit);
// Post a message on port1 when the button is clicked
function onSubmit(e) {
e.preventDefault();
var message = document.getElementById("message").value;
var msgObj = {
message: message
};
port1.postMessage(msgObj);
}
Child Iframe
<!-- page2.html -->
<form id="iframe-form">
<label for="iframe-message"
>Send message to the parent
<input id="iframe-message" type="text" />
</label>
<button type="submit">Send</button>
</form>
<h2>Message received is shown here:</h2>
<div id="message-from-parent"></div>
</body>
<script src="./child.js"></script>
// child.js
(function () {
var port2;
// Listen for the intial port transfer message
window.addEventListener("message", initPort);
// Setup the transfered port
function initPort(e) {
if (e.data === "init") {
port2 = e.ports[0];
port2.onmessage = onMessage;
} else {
var msgObj = e.data;
onMessage({
data: msgObj
});
}
}
// Handle messages received on port2
function onMessage(e) {
var $messageContainer = document.querySelector("#message-from-parent");
$messageContainer.textContent = e.data.message;
port2.postMessage("Message received by iframe");
}
// Sending message to the parent
var $form = document.querySelector("#iframe-form");
$form.addEventListener("submit", function (e) {
e.preventDefault();
var message = document.querySelector("#iframe-message").value;
port2.postMessage(message);
});
})();