Development

Embedding a 100% height iframe in SharePoint Online Modern pages

Before SharePoint Online, I embedded cross-origin iframes within web applications using the method described here. It uses a JavaScript Event Listener to receive requests from the child, such as resizing an iframe object on the parent to match the height of the content within. I modified this code to also fire an Event to the parent to scroll to the top when a page loads within the iframe. This method works even with Microsoft’s recent removal of some classes from the scrollable div of Modern SharePoint Online pages.

You must have access to the code of the webapp being loaded within the iframe in order to embed an auto-sizing iframe in a Modern SharePoint Online page. If not, this won’t work. And as far as I know, it’s not possible to resize the height of an iframe without knowing the page height of the content within the iframe. To archive this, you’ll need a javascript event fired from the body of the iframe content. You’ll also need to embed some code on your SharePoint Online Modern page – I use the Modern Script Editor Webpart to embed custom code to our Modern SharePoint Online pages.

To get started, add the following code to the pages you’re loading within the iframe. This code will detect the height of the content and send this via an Event Listener to the parent document. I’m using jQuery to fire on document ready, but this may not be necessary.

<script>
	// Size the parent iFrame
	function iframeResize() {
		var height = $('body').outerHeight(); // IMPORTANT: If body's height is set to 100% with CSS this will not work.
		parent.postMessage("resize::"+height,"*");
	}
	// jQuery document ready
	$(document).ready(function() {
		// Send iFrame resize request to parent on any link click within child. This will temporarily cause the iFrame to resize larger than needed to avoid jankyness.
		$("a").click(function(){
			parent.postMessage("tempresize","*");
		});
		// scroll to top of parent on page load
		parent.postMessage("topofwindow","*");
		// Resize iframe
		setInterval(iframeResize, 1000);
	});
</script>

On the parent document within SharePoint Online you’ll want to use the following code using the Modern Script Editor Webpart. The code contains a little CSS and JavaScript. The CSS styling is to remove any padding and hides the Comments div making the integration look a little more seamless. The JavaScript code is where you define the iframeID and appUrl. In the event the SharePoint page is loaded within the iOS or Android app, the page will automatically redirect to the app itself instead of attempting to load within the iFrame. The JavaScript also contains 3 Event Listeners.

  • resize receives the body height of the iframe content and resizes the iframe to match.
  • topofwindow will receive an event from the iframe to cause the SharePoint parent document to scroll to the top of the scrollable div. This is like scrolling to the top of Window, but SharePoint Online Modern uses scrollable regions instead. This is achieved using the data-automation-id attribute of the div.
  • tempresize listens for an link clicks in the iframe. If it detects a click, it will resize the iframe height temporarily to avoid jankyness. For example, the first document may have a height of 100 pixels but the second loaded document may have a height of 2000px. There’s a delay between the iframe content loading and the iframe being resized. In some cases this could cause content to appear “cut off” to the user for a second. This function should resize the height of the iframe larger than needed and then it’s resized again by the resize function. You could probably also achieve something similar by hiding the iframe on a click, and then re-showing it on resize.
<!-- Hide some elements of SharePoint Online page -->
<style>
    #CommentsWrapper { display: none; }
    #spSiteHeader { display: none; }
    #edh-iframe { margin-bottom: -10px; }
    #SharePointApp { display:none; }
    footer { display: none; }
</style>

<!-- Define the iFrame -->
<iframe id="edh-iframe" width="100%" height="800" border="0" frameborder="0" scrolling="no" onload="scroll(0,0);">Unable to display iframe content</iframe>

<!-- Javascript to load iFrame, redirect (if neccessary), and perform resize -->
<script type='text/javascript'>
	//Define the iFrame URL
	var appUrl = "https://companydirectory.graybarcanada.com"

	//Define iFrame ID 
	var iframeId = "edh-iframe"

	//Redirect to appUrl if userAgent is SharePoint Online (for iOS/Android app support)
	if (navigator.userAgent.includes("SharePoint")) {
		window.location.href = appUrl;
	}

	//Load the iFrame
	document.getElementById(iframeId).src = appUrl;

	// Create IE + others compatible event handler
	var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
	var eventer = window[eventMethod];
	var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

	// Listen to message from child window
	eventer(messageEvent,function(e) {
		// If the message is a resize frame request
		if (e.data.indexOf('resize::') != -1) {
			var height = e.data.replace('resize::', '');
			document.getElementById(iframeId).style.height = height+'px';
		}
		// If the message is top of window request
		if (e.data.indexOf('topofwindow') != -1) {
			//window.scrollTo(0, 0); 
			var elmnt = document.querySelector("[data-automation-id='contentScrollRegion']");
			elmnt.scrollTop = 0;
		}
		if (e.data.indexOf('tempresize') != -1) {
			document.getElementById(iframeId).style.height = '1920px';
		}
	} ,false);
</script>

And that’s it. The iframe in SharePoint Online should now automatically resize to the height of the content within the iframe.

Published by
Cormang