17

Generally I am against the use of iframes, but it solved a particular problem of mine.

The thing is that I have a tinyMCE-editor at a webpage. After the user have made the content using this editor the content is sent as HTML to a web application. This content is then displayed in a div. Thing is that tinyMCE often add styles with position absolute and things that break with the rest of the web applicaiton.

When testing I found out that the new HTML 5 iframe srcdoc="<p>Some HTML</p>" and seamless="true" was perfect for my situation. It looked seamless and the contents style and my style was intact. Sadly I now see that the HTML5 srcdoc attribute is not yet supported by Android (http://w3schools.com/html5/tryit.asp?filename=tryhtml5_iframe_srcdoc yields different result in chrome and android browser).

So the question is: Is there any alternative to the iframe srcdoc which will preserve all style of the received content and contain it in a div?

Sindre
  • 3,880
  • 2
  • 26
  • 39
  • change editor ? there is many editors on the net – zb' Nov 04 '12 at 00:55
  • 1
    also you may like this example which demonstrate working with iframe on same origin. http://jsfiddle.net/oceog/r4VPr/ – zb' Nov 04 '12 at 01:06
  • Thanks, that did the trick with some modifications! – Sindre Nov 04 '12 at 11:45
  • I'll point out that Edge doesn't seem to support `srcDoc` either - https://wpdev.uservoice.com/forums/257854-microsoft-edge-developer/suggestions/6261334-iframe-srcdoc-attribute – nevada_scout Jul 19 '18 at 13:25

3 Answers3

22

You can write to the document of an iframe like this:

const html = '<body>foo</body>';
const iframeDocument = document.querySelector('iframe#foo').contentDocument;
const content = `<html>${html} </html>`;
iframeDocument.open('text/html', 'replace');
iframeDocument.write(content);
iframeDocument.close();
vhs
  • 9,316
  • 3
  • 66
  • 70
Chris Lundie
  • 6,023
  • 2
  • 27
  • 28
9

As suggested by eicto by comment, jquery could be used to fill an iframe at the ready-event. In order to adjust the height of the iframe to the height of the content some dirty hacks had to be applied, but the code I ended up using is more or less:

HTML

<!-- IMPORTANT! Do not add src or srcdoc -->
<!-- NOTICE!    Add border:none to get a more "seamless" integration -->
<iframe style="border:none" scrolling="no" id="myIframe">
    Iframes not supported on your device
</iframe>

JS

// Wait until iFrame is ready (body is then available)
$('#myIframe').ready(function() {

    var externalHtml = '<p>Hello World!</p>';

    // Find the body of the iframe and set its HTML
    // Add a wrapping div for height hack
    // Set min-width on wrapping div in order to get real height afterwords
    $('#myIframe').contents().find('body')
        .html('<div id="iframeContent" style="min-width:'+$('body').width()+'px">'
            +externalHtml
            +'</div>'
    );

    // Let the CSS load before getting height 
    setTimeout(function() {
        // Set the height of the iframe to the height of the content
         $('#myIframe').css('height', 
             $('#myIframe').contents()
             .find('#iframeContent').height() + 'px' 
         );
    },50);
});
Sindre
  • 3,880
  • 2
  • 26
  • 39
  • 1
    Just don't do this if any of the content is untrusted and unsandboxed--as may be possible if user is pasting in code snippets... – Brett Zamir Dec 19 '12 at 12:53
1

Use the new Data URI Scheme. Example:

var content = "<html></html>";
document.getElementById("my_iframe_id").src = "data:text/html;charset=UTF-8," + content;
  • 1
    see http://msdn.microsoft.com/en-us/library/cc848897(v=VS.85).aspx Data URIs are supported only for the following elements and/or attributes. object (images only) img input type=image link CSS declarations that accept a URL, such as background, backgroundImage, and so on. – jbiddick Feb 08 '18 at 20:44