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.
Last active
October 17, 2022 08:11
-
-
Save marcelkornblum/d3b6d18168eaf90df4430b9da4d63ed9 to your computer and use it in GitHub Desktop.
iFrame with dynamic resizing based on child dimensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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 | |
}; | |
}()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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