Quantcast
Channel: Resizing an iframe based on content - Stack Overflow
Viewing all articles
Browse latest Browse all 28

Answer by Ogglas for Resizing an iframe based on content

$
0
0

I have been reading a lot of the answers here but nearly everyone gave some sort of cross-origin frame block.

Example error:

Uncaught DOMException: Blocked a frame with origin "null" fromaccessing a cross-origin frame.

The same for the answers in a related thread:

Make iframe automatically adjust height according to the contents without using scrollbar?

I do not want to use a third party library like iFrame Resizer or similar library either.

The answer from @ChrisJacob is close but I'm missing a complete working example and not only links. @Selvamani and @latitov are good complements as well.

https://stackoverflow.com/a/3219970/3850405

I'm using width="100%" for the iframe but the code can be modified to work with width as well.

This is how I solved setting a custom height for the iframe:

Embedded iframe:

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8" /><meta name="description"          content="Web site" /><title>Test with embedded iframe</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><iframe id="ifrm" src="https://localhost:44335/package/details?key=123" width="100%"></iframe><script type="text/javascript">        window.addEventListener('message', receiveMessage, false);        function receiveMessage(evt) {            console.log("Got message: " + JSON.stringify(evt.data) +" from origin: " + evt.origin);            // Do we trust the sender of this message?            if (evt.origin !== "https://localhost:44335") {                return;            }            if (evt.data.type === "frame-resized") {                document.getElementById("ifrm").style.height = evt.data.value +"px";            }        }</script></body></html>

iframe source, example from Create React App but only HTML and JS is used.

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8" /><meta name="description"          content="Web site created using create-react-app" /><title>React App</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script type="text/javascript">        //Don't run unless in an iframe        if (self !== top) {            var rootHeight;            setInterval(function () {                var rootElement = document.getElementById("root");                if (rootElement) {                    var currentRootHeight = rootElement.offsetHeight;                    //Only send values if height has changed since last time                    if (rootHeight !== currentRootHeight) {                        //postMessage to set iframe height                        window.parent.postMessage({ "type": "frame-resized", "value": currentRootHeight }, '*');                        rootHeight = currentRootHeight;                    }                }            }                , 1000);        }</script></body></html>

The code with setInterval can of course be modified but it works really well with dynamic content. setInterval only activates if the content is embedded in a iframe and postMessage only sends a message when height has changed.

You can read more about Window.postMessage() here but the description fits very good in what we want to achieve:

The window.postMessage() method safely enables cross-origincommunication between Window objects; e.g., between a page and apop-up that it spawned, or between a page and an iframe embeddedwithin it.

Normally, scripts on different pages are allowed to access each otherif and only if the pages they originate from share the same protocol,port number, and host (also known as the "same-origin policy").window.postMessage() provides a controlled mechanism to securelycircumvent this restriction (if used properly).

https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage


Viewing all articles
Browse latest Browse all 28

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>