while($alive) LiveAndLearn();

JavaScript, PHP, C# and Life in Viet Nam

Adding Dynamic Contents to IFrames

with 32 comments

I found myself in a situation this weekend where I needed to add some contents to an iframe dynamically, and naive as I were, I kind of assumed it was straight forward to do it using the DOM.

To try it out I created a simple HTML page adding a div element and a function onPageLoad which would be called when the page was loaded and here I would place my code to dynamically add some contents to the iframe which I also decided to create dynamically just for the sport of it.

<html>
   <head>
      <title>Adding Dynamic Contents to IFrames</title>

      <script type="text/javascript">
         function onPageLoad()
         {
            var iframe = document.createElement("iframe");
            var canvas = document.getElementById("canvas");
            canvas.appendChild(iframe);

            var div = iframe.document.createElement("div");
            div.style.width = "50px"; div.style.height = "50px";
            div.style.border = "solid 1px #000000";
            div.innerHTML = "Hello IFrame!";
            iframe.document.body.appendChild(div);
         }
      </script>
   </head>

   <body onload="onPageLoad();">
      <div id="canvas" style="border: solid 1px #000000; height: 500px; width: 500px;"></div>
   </body>
</html>

My first attempt failed both in Internet Explorer and Firefox, worst in Firefox which announced that iframe.document didn’t have any properties, and in Internet Explorer the div element was placed after the iframe element not inside intended.I did some research using Google in an attempt to get some qualified help and I learned that there are just as many ways to get the iframe’s document as there are browser platforms, almost. But happy to have found myself in some kind of progress I updated my code for the onPageLoad function.

function onPageLoad()
{
   var iframe = document.createElement("iframe");
   var canvas = document.getElementById("canvas");
   canvas.appendChild(iframe);

   var doc = null;
   if(iframe.contentDocument)
      // Firefox, Opera
      doc = iframe.contentDocument;
   else if(iframe.contentWindow)
      // Internet Explorer
      doc = iframe.contentWindow.document;
   else if(iframe.document)
      // Others?
      doc = iframe.document;

   if(doc == null)
      throw "Document not initialized";

   var div = doc.createElement("div");
   div.style.width = "50px"; div.style.height = "50px";
   div.style.border = "solid 1px #000000";
   div.innerHTML = "Hello IFrame!";
   doc.body.appendChild(div);
}

My progress was limited, I succeeded in eliminating the error when viewing the page with Firefox, but now it no longer worked in Internet Explorer which announced that doc.body was null.You might wonder why I choose to append the iframe to an element which already exists in the DOM before appending anything to the iframe’s document, that is because I found out that as long as the iframe is not appended to the DOM the document property will not be initialized, this happened both for Internet Explorer and Firefox.Reading the post, I had found, a little more thoroughly I found out that there was a way to write to the iframe’s document using the document.write method. Trying it out I changed my onPageLoad function to write a small text.

function onPageLoad()
{
   var iframe = document.createElement("iframe");
   var canvas = document.getElementById("canvas");
   canvas.appendChild(iframe);

   var doc = null;
   if(iframe.contentDocument)
      // Firefox, Opera
      doc = iframe.contentDocument;
   else if(iframe.contentWindow)
      // Internet Explorer
      doc = iframe.contentWindow.document;
   else if(iframe.document)
      // Others?
      doc = iframe.document;

   if(doc == null)
      throw "Document not initialized";

   doc.open();
   doc.write("Hello IFrame!");
   doc.close();
}

Finally I was able to render the page both in Internet Explorer and Firefox with the same result, I was doing some real progress. Now I could of course create all of my contents in the iframe this way, as the post I found using Google suggested, but it wouldn’t be that dynamic plus I would have to do a lot of string manipulation in order to add event handlers and so on.

My biggest problem being that I only had access to an amputated version of the document element in the iframe I started thinking about ways in which I could make a callback function from the iframe sending the document element to the parent. But in the end the solution was extremely simple and perhaps some of you who read this whill think that it is obvious.

The real trick for making this work only occurred to me while writing this, I tried to add my div element to the iframe’s document element right after the part where I write “Hello IFrame!” as shown above, this gave me the following changed onPageLoad function.

function onPageLoad()
{
   var iframe = document.createElement("iframe");
   var canvas = document.getElementById("canvas");
   canvas.appendChild(iframe);

   var doc = null;
   if(iframe.contentDocument)
      // Firefox, Opera
      doc = iframe.contentDocument;
   else if(iframe.contentWindow)
      // Internet Explorer
      doc = iframe.contentWindow.document;
   else if(iframe.document)
      // Others?
      doc = iframe.document;

   if(doc == null)
      throw "Document not initialized";

   doc.open();
   doc.write("Hello IFrame!");
   doc.close();

   var div = doc.createElement("div");
   div.style.width = "50px"; div.style.height = "50px";
   div.style.border = "solid 1px #000000";
   div.innerHTML = "Hello IFrame!";
   doc.body.appendChild(div);
}

The magic appeared, now I got my div element added to the iframe’s document element right after the text I wrote using the write method. The next natural step was to leave out the call to the write method. Calling the open method following by the close method will put the iframe’s document in such a state that you will be able to use the appendChild method.

The only thing left to do after this was to wrap it all up nicely in a class, below is a simplified version of what an IFrame class might look like. Notice that the parent element must be added to the DOM already, but in most cases that shouldn’t cause any problems.

function IFrame(parentElement)
{
   // Create the iframe which will be returned
   var iframe = document.createElement("iframe");

   // If no parent element is specified then use body as the parent element
   if(parentElement == null)
      parentElement = document.body;

   // This is necessary in order to initialize the document inside the iframe
   parentElement.appendChild(iframe);

   // Initiate the iframe's document to null
   iframe.doc = null;

   // Depending on browser platform get the iframe's document, this is only
   // available if the iframe has already been appended to an element which
   // has been added to the document
   if(iframe.contentDocument)
      // Firefox, Opera
      iframe.doc = iframe.contentDocument;
   else if(iframe.contentWindow)
      // Internet Explorer
      iframe.doc = iframe.contentWindow.document;
   else if(iframe.document)
      // Others?
      iframe.doc = iframe.document;

   // If we did not succeed in finding the document then throw an exception
   if(iframe.doc == null)
      throw "Document not found, append the parent element to the DOM before creating the IFrame";

   // Create the script inside the iframe's document which will call the
   iframe.doc.open();
   iframe.doc.close();

   // Return the iframe, now with an extra property iframe.doc containing the
   // iframe's document
   return iframe;
}

I saved the class in a file called IFrame.js, and using this class simplified my test page to the following.

<html>
   <head>
      <title>Adding Dynamic Contents to IFrames</title>

      <script type="text/javascript" src="IFrame.js"></script>
      <script type="text/javascript">
         function onPageLoad()
         {
            var canvas = document.getElementById("canvas");
            var iframe = new IFrame(canvas);

            var div = iframe.doc.createElement("div");
            div.style.width = "50px"; div.style.height = "50px";
            div.style.border = "solid 1px #000000";
            div.innerHTML = "Hello IFrame!";
            iframe.doc.body.appendChild(div);
         }
      </script>
   </head>

   <body onload="onPageLoad();">
      <div id="canvas" style="border: solid 1px #000000; height: 500px; width: 500px;"></div>
   </body>
</html>
share save 171 16 Adding Dynamic Contents to IFrames

Written by Thomas Bindzus

December 24th, 2007 at 12:37 am

32 Responses to 'Adding Dynamic Contents to IFrames'

Subscribe to comments with RSS or TrackBack to 'Adding Dynamic Contents to IFrames'.

  1. [...] Thomas Bindzus wrote an interesting post today on Adding Dynamic Contents to IFramesHere’s a quick excerptMy progress was limited, I succeeded in eliminating the error when viewing the page with Firefox, but now it no longer worked in Internet Explorer which announced that doc.body was null. You might wonder why I choose to append the … [...]

  2. Thanks for this code saved my neck :)
    it worked like a charm on Firefox and ie

  3. Heres another article on javascript resizing for iframes.

    colin

    9 Apr 08 at 22:49:47

  4. Another great example of how broken the whole web browser business is.

    George

    30 Jul 08 at 20:29:51

  5. How would you add attributes to the iframe – like width=”550″ scrolling=”no” height=”700″ and such? Great articles by the way

    Jeromy

    18 Sep 08 at 03:53:47

  6. here’s how you add attributes to the iframe:

    var frm=document.body.appendChild(document.createElement(‘IFRAME’));
    frm.src=’http://www.google.com’;
    frm.id=”masterdiv”
    frm.width=”150px”; frm.height=”150px”;
    frm.marginWidth=”0″; frm.marginHeight=”0″;
    frm.scrolling=”no”;
    frm.style.position=”absolute”;frm.style.left=”10px”; frm.style.top=”10px”;

    mahesh

    23 Sep 08 at 06:56:55

  7. Thanks for this article! I was banging my head against the same wall and didn’t find any other good solutions myself or online.

    I might be able to just use a scrolling DIV, but there are times when an iframe is preferable.

    Kendall Brookfeld

    28 Jan 09 at 11:56:17

  8. Brilliant!!

    The perfect blend of problem description, logic path development with each step fully coded, a very useful wrapper class, an example using the wrapper, and it works!!

    I have only tested in FireFox … but your cross browser selectivity looks solid.

    I salute you!!

    Your explanation about creating the doc property still has me wondering how you figured that out! I have studied the Rhino book a lot … and that cleverness eludes me.

    I would enjoy your valued opinion on web development text books and online resources. (I went through dozens of online sites before stumbling upon your gift to all.)

    Thank you for your efforts to share knowledge with others.

    The comment about using a scrolling div was also very helpful to this novice.

    The author nickname “DrJokepu”‘s comments in the following was also helpful for styling the iframe’s internal content:

    http://stackoverflow.com/questions/217776/how-to-apply-css-to-iframe

    Tom Hollister

    7 Feb 09 at 13:26:07

  9. I am humbled by the gratitude for my simple article, over time I have had a lot of visits to this post. I didn’t realize when I wrote it that so many people would still be using iframes and in desperate need for a post like mine.

    It gives me great happiness that I have been able to share, since I have often been in need and found tons of useful information on other peoples blogs about JavaScript especially, programming in general, management and life itself :-)

    I don’t posses a whole lot of text books on web development, my favorite book of all times about JavaScript is as you mentioned yourself the Rhino book from O’Reilly (JavaScript: The Definitive Guide by David Flanagan ISBN: 0-596-00048-0). It actually happens to be the only book I posses about web development, even though I have been working with web development for 10 years now :-)

    When writing the blog on iframes I spend an entire day searching on Google for good references, and that is normally the way I find online resources, but I never stick to one particular site. It’s a bit embarrassing that I didn’t include any references for my post, but Mozilla’s own developer pages helped me a lot.

    Thomas Bindzus

    8 Feb 09 at 10:52:04

  10. Great post.

    I am building a system that will be integrating a userscript (greasemonkey script) into a website via iframe using this type of scripting.

    Should this still be able to work? I assume cross browser might be an issue, but as long as i can get it to work on *A* browser thats all I care about.

    Travis McCrea

    21 Feb 09 at 04:26:08

  11. Hi Travis,

    It is a little hard to say based on what you write, but recently I had a similar problem, I loaded another page into an iframe and needed to access JavaScript functions and objects from the page in the iframe.

    Let’s say the page in the iframe has a function:

    function doTest()
    {
       alert("This is a test!");
    }
    

    Then you can access this function from your main page by accessing the iframe.contentWindow in the following way

    var iframe = new IFrame(document);
    
    // Here I set iframe.src to point to my page
    
    // Call the function from the iframe
    iframe.contentWindow.doTest();
    

    Hope this helps you out, the contentWindow is available both for IE and FF (at least for IE6 and FF3). If you have more questions then feel free to contact me :-)

    Best wishes
    - Thomas

    Thomas Bindzus

    21 Feb 09 at 19:15:20

  12. Excellent post saved my time. Thanks a lot Thomas

    Ramya

    12 May 09 at 11:52:17

  13. Hi,
    I need to remove the frame border of the Iframe that is created dynamically. How to do this?

    I tried with
    frm.frameborder=”0″

    Irshad

    26 May 09 at 18:47:54

  14. Hi there,

    Must agree – this is an excellent post.

    Works perfectly in Firefox, but in IE8, I am getting a “Permission Denied” error when the code attempts to modify the contents of the iFrame. I believe this is because the default page of the dynamic iFrame is “about:blank” when no src attribute is set, and then IE8 thinks you are attempting to cross domains to modify the iFrame.

    Does this theory sound correct? Any thoughts?

    Thanks!

    -Will

    Will

    16 Jun 09 at 03:11:48

  15. good one mate, life saver, thank you

    rachid

    29 Sep 09 at 04:55:35

  16. [...] mir die Idee, das mit einem iFrame mit dynamischem Content per JS zu machen. Als Anregung diente dieser Post. Hier mein [...]

  17. Thanks for this useful & understandable article.

    Sedat Kumcu

    22 Dec 09 at 20:04:58

  18. Perfect tutorial and very useful for my purpose of uploading images in the background via an iframe.

    However, I have a problem and can’t seem to find a solution via google.

    I am generating an Iframe, generating a dom object for a form and copying a input file form from the main document into the iframes form object. Then I am sending the form to the server in order to upload the file.
    This works perfectly well in Firefox, but not in IE8, Safari nor Chrome.
    I figured out that if I use an iframe based on a html document that provides the header meta tag Content-Type text/html then it also works in all other browsers.
    Now the question is how do I do that with your iframe fuction?
    I know that there is a Javascript function named setContentType, but I can’t seem to figure on how to implement it.

    Thanks in advance and keep up the great tutorials.

    //Black

    Black

    6 Feb 10 at 21:41:16

  19. Hi Thomas, i just read your article while searching for a solution to replace the whole html node in an iframe, sadly, for now, i still haven’t found a solution.

    Could i bother you to ask you to think about this for a few minutes and see if you can come up with anything?

    It would be really awesome if it were possible.

    Thank a lot in advance.

    Bereczki Andrei

    10 Mar 10 at 20:24:40

  20. Hello Thomas,
    Can u suggest me how to display Doc, Rtf file inside Iframe, I am using OS windows 7, I can display Pdf, Htm and XML but not able to display doc, Rtf file type

    Thanks in Advance
    Faizal

    Faizal

    16 Jun 10 at 19:21:26

  21. Inside Iframe Coming Blank for me While trying to display Rtf and Doc file type.

    Faizal

    16 Jun 10 at 19:23:39

  22. Dear Faizal,

    I am not aware of any way to force this behavior, to my knowledge this depends on the plugins which are installed into your browser, thus the reason you can successfully see PDF files is probably because you have a browser plugin for this.

    Kind regards
    - Thomas

    Thomas Bindzus

    23 Jun 10 at 22:54:30

  23. Sir,

    Using one iFrame I want to display no. pdfs passing a pdf name parametrically. Pl. Guide me. Awaiting your quick response. Thanks

    Pandit Parantap

    28 Jun 10 at 13:44:10

  24. I’m sorry, but I don’t understand your question, please specify in more details what you are trying to achieve, thank you.

    Thomas Bindzus

    28 Jun 10 at 15:52:32

  25. Oh, I love you!
    You’re awesome.

    I had a huge headache until I came to this site.
    Things are slightly different when appending a form to an iframe, though..
    Let’s see..
    01) I need to have a div.
    02) I need to append my iframe to that div.
    03) I need to create another div, (we’ll call it div2)
    04) I need to append div2 into my iframe
    05) I need to append my form into div2

    You just saved my head from exploding.
    4hours of searching, 30minutes to read and understand your article.

    Justin

    6 Jul 10 at 05:32:55

  26. This post has been ridiculously helpful. I was running into a problem with having a form submit to an iframe (for ajax-like form submissions) twice without having the page reload. The first time it worked perfectly fine, but on the second form submission I would get a javascript error saying that the frame’s document body could be found even though it was quite obviously there when I looked at it with Firefox’s DOM inspector.

    Found this post and used what your wrote to get my stuff fixed up. A huge thanks. Seriously, I’m really happy I found this page because I likely would’ve been banging my head against the wall by now if I hadn’t.

    David

    16 Jul 10 at 02:04:28

  27. Meant to write “I would get a javascript error saying that the frame’s document body could not be found…”

    David

    16 Jul 10 at 02:05:55

  28. Hi,

    Thanks for this nice article. But actually I have some different problem but related to iframe. I want to access the Url which is clicked inside an iframe. I tried location, src etc etc. If the domain is same it works for me but if domain is not same then it gives me permission denied to get location href property of iframe.

    Please suggest me if anything to do.

    Neeraj

    Neeraj

    3 Aug 10 at 16:35:50

  29. [...] wrapping Servlet Filter, there are no elegant solution regarding POST requests (aside possibly an iFrame technique, but we are getting in a dirty area in my opinion and this won’t work for posting [...]

  30. Hi Thomas,
    This was realy very useful stuff. Thanks a lot. It helped me lot.

    Madeswaran

    7 Sep 11 at 15:43:44

  31. Really helpful.

    Xipan Xiao

    22 Sep 11 at 21:32:22

  32. GREAT! I had severe troubles with IExplorer because documentContet.body was null! Now I’ve solved
    Thanks a lot!

    Marco Perasso

    27 Sep 11 at 16:18:16

Leave a Reply

Switch to our mobile site