Skip to content

Instantly share code, notes, and snippets.

@marcelkornblum
Last active October 17, 2022 08:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcelkornblum/d3b6d18168eaf90df4430b9da4d63ed9 to your computer and use it in GitHub Desktop.
Save marcelkornblum/d3b6d18168eaf90df4430b9da4d63ed9 to your computer and use it in GitHub Desktop.
iFrame with dynamic resizing based on child dimensions

A series of files capturing a way to do a resizable iFrame integration where the child / iframed content is able to tell the parent page to resize the iFrame container, avoiding scrolbars etc on the container edge for deynamic content, or just content that resizes with screen size.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>iFrame Child</title>
<script type="text/javascript" src="iframe-messenger.js"></script>
</head>
<body>
<p>Content goes here.<p>
<div>
<a href="#" onClick="addHeight()">Add new content</a>
</div>
</body>
</html>
(function () {
/*
Reference to the script element. Used to read configuration data attributes
*/
var scriptEl = null;
/*
Reference to the iframe element
*/
var iframeEl = null;
/*
Ensures we only run this script once
*/
var hasRun = false;
/*
Self-executing start function
*/
(function start () {
if (document.readyState === 'complete' || document.readyState === 'loaded' || document.readyState === 'interactive') {
setup();
} else {
document.addEventListener('DOMContentLoaded', setup);
}
})();
function setup () {
if (hasRun) return;
// Get the script elment
scriptEl = document.getElementById('iframe-controller');
if (scriptEl) {
if (scriptEl.hasAttribute('data-iframe-id')) {
iframeEl = document.getElementById(scriptEl.getAttribute('data-iframe-id'));
if (iframeEl) {
// Attach handler for post messages
attachPostMessageHandler();
} else {
console.error('Iframe handler - unable to locate the iframe element with id: \'' + scriptEl.getAttribute('data-iframe-id') + '\'');
}
}
} else {
console.error('Iframe handler - unable to locate the script element with id: \'iframeHandler\'');
}
hasRun = true;
}
function attachPostMessageHandler () {
window.onmessage = (e) => {
if (Object.prototype.hasOwnProperty.call(e.data, 'pageHeight')) {
var height = e.data.pageHeight;
iframeEl.style.height = `${height}px`;
} else if (Object.prototype.hasOwnProperty.call(e.data, 'resetScroll')) {
var scrollPos = iframeEl.getBoundingClientRect().top + document.documentElement.scrollTop;
document.documentElement.scrollTop = scrollPos;
}
};
}
return {
// nothing
};
}());
const heightUpdateEvent = new Event('heightUpdate');
window.addEventListener('heightUpdate', () => {
this.sendPostMessage();
});
window.onload = () => this.sendPostMessage();
window.onresize = () => this.sendPostMessage();
sendPostMessage = () => {
const height = window.document.body.clientHeight;
window.parent.postMessage({ pageHeight: height }, '*');
};
addHeight = () => {
const newDiv = document.createElement("p");
newDiv.innerHTML = "this is a new piece of content.";
document.body.append(newDiv);
window.dispatchEvent(heightUpdateEvent);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>iFrame Parent</title>
<style>
html {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
body {
padding: 10px;
margin: 0;
width: auto;
height: auto;
background-color: #84929B;
color: #333333;
font-family: 'Helvetica', 'Arial', sans-serif;
}
iframe {
width: 100%;
height: auto;
border: none;
overflow-x: auto;
overflow-y: hidden;
outline: 2px solid red;
height: 600px;
}
</style>
<!--
Iframe Controller Script
Used by iframe app to control the height of the iframe element and the
scroll position of the page via the postMessage API. If the iframe app
is being loaded from a remote domain, then the server should include an
Access-Control-Allow-Origin header in responses to allow cross origin
communication. Ideally this script should be loaded from the same location
as the iframe app to allow changes to be made to it if required.
Attributes
id: Required. Should not be changed. Allows the script to find its own
embed.
data-iframe-id: Required. Can be changed. Must match id attribute of
iframe element
-->
<script id="iframe-controller"
src="iframe-controller.js"
data-iframe-id="iframe-element"
type="text/javascript">
</script>
</head>
<body>
<h2>Dynamic iFrame Parent Page</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Eu tincidunt tortor aliquam nulla facilisi cras fermentum odio. Morbi non arcu risus quis varius quam quisque id. At quis risus sed vulputate odio ut enim. Massa massa ultricies mi quis hendrerit. In vitae turpis massa sed elementum tempus. Nunc eget lorem dolor sed viverra ipsum nunc. Condimentum mattis pellentesque id nibh. Pulvinar pellentesque habitant morbi tristique. Ultricies mi eget mauris pharetra. Quam nulla porttitor massa id. Habitant morbi tristique senectus et. Mi sit amet mauris commodo quis imperdiet.
</p>
<iframe id="iframe-element" src="child.html"></iframe>
<p>
In hac habitasse platea dictumst vestibulum rhoncus. Ipsum nunc aliquet bibendum enim. Risus commodo viverra maecenas accumsan lacus vel facilisis volutpat. Pretium vulputate sapien nec sagittis aliquam malesuada bibendum. Neque vitae tempus quam pellentesque nec. Feugiat nibh sed pulvinar proin gravida hendrerit lectus a. Ultricies mi eget mauris pharetra et ultrices neque. Pulvinar etiam non quam lacus suspendisse faucibus interdum posuere. Urna porttitor rhoncus dolor purus non. Purus sit amet luctus venenatis lectus magna fringilla urna porttitor. Lectus arcu bibendum at varius vel pharetra vel turpis nunc. Nibh tortor id aliquet lectus. Consectetur adipiscing elit ut aliquam purus. Eget egestas purus viverra accumsan in nisl nisi scelerisque eu.
</p>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment