Microjournal
Resizing an iframe using postMessage
April 17, 2014
How to keep an embedded iframe height in sync with its parent page by exchanging messages between the host and the child document.
Resizing an embedded iframe across domains comes down to sending the iframe height to the parent page and letting the host adjust the element dynamically. The pattern relies on window.postMessage so that the parent and child stay in sync without having to expose the embedded page.
Listener on the host page
The container page listens for messages that originate from the iframe and mutates the matching element's height whenever the payload changes.
(function () {
var listenerMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var messageHandler = function (event) {
if (event.origin !== "http://www.checktheorigin.com") {
return;
}
if (typeof event.data === "object" && event.data.frame && event.data.height) {
document.getElementById(event.data.frame).style.height = event.data.height + "px";
}
};
window[listenerMethod](listenerMethod === "attachEvent" ? "onmessage" : "message", messageHandler, false);
})();
Sender inside the iframe
The embedded experience gathers the rendered height (after it finishes its own DOM updates) and posts that information up to the host.
(function () {
var labels = document.querySelectorAll("label");
var index = labels.length;
while (index--) {
var label = labels.item(index);
var text = label.textContent;
if (label.parentNode.classList.contains("required")) {
text += "*";
}
label.nextElementSibling.setAttribute("placeholder", text);
}
if (parent.postMessage) {
parent.postMessage(
{
height: document.getElementById("content").offsetHeight,
frame: window.name,
},
"*",
);
}
})();
With the host and iframe both handling their responsibilities, the cross-domain iframe fits the content without the user ever seeing scrollbars.