Adding Dynamic Contents to IFrames

转载 2012年08月14日 15:24:38

http://thomas.bindzus.me/2007/12/24/adding-dynamic-contents-to-iframes/



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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<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>

HTML Iframes,html一个有点技术含量的知识

添加一个iframe的语法: URL指向的位置独立的页面。 Iframe——设置高度和宽度 高度和宽度属性用于指定iframe的高度和宽度。 默认属性值中指定的像素,但它们也可以在...
  • u014356565
  • u014356565
  • 2014年03月28日 11:05
  • 517

父元素与子iframe相互获取变量和元素对象

父中:    var count = 1; ------------------------------------------------------------- 子iframe...
  • xiebiaoling
  • xiebiaoling
  • 2013年09月13日 09:39
  • 4979

python学习进阶(一)------学习contents_xml.py

在学习contents_xml.py 脚本中,发现该脚本使用到optparse lib,我们需要了解optparse的使用。通过网络博客了解到optparse库的使用 参考博客:1)htt...
  • fengxianger
  • fengxianger
  • 2016年07月15日 13:58
  • 645

Oracle RAC相关问题——adding cluster entries toinittab

Oracle RAC相关问题——adding cluster entries toinittab   1.      ASM磁盘问题 2.      /etc/hosts 3.      BU...
  • notbaron
  • notbaron
  • 2016年06月19日 11:32
  • 30388

HTML 5通过sandbox属性提升iFrame的安全性

转自:InfoQ 作者 Abel Avram 译者 张龙 发布于 ...
  • Vanessa219
  • Vanessa219
  • 2010年02月05日 10:59
  • 1332

could not list the contents of folder 的解决方案

我在使用PHPstorm的时候,遇到了could not list the contents of folder的错误,使用外部的FTP工具是能正常连接到服务器的,但是在PHPStorm上却不行,纠结...
  • u012369749
  • u012369749
  • 2017年11月07日 10:36
  • 397

iOS 错误提示

在这里先记录下错误提示,暂时还未找到解决办法,如果你知道是什么原因,请告知下,谢谢!!!2016-01-28 15:39:33.817 MosProject[5965:1900978] UIAcces...
  • qq_29284809
  • qq_29284809
  • 2016年01月30日 10:43
  • 538

iOS动画系列之二--CALayer的contents属性的应用

1> CALayer 有一个属性叫做contents,这个属性的类型被定义为id,意味着它可以是任何类型的对象。在这种情况下,你可以给contents属性赋任何值,你的app仍然能够编译通过。但是,在...
  • u013915422
  • u013915422
  • 2016年05月29日 12:24
  • 1412

Altium Designer 出现错误提示(警告)adding items to hidden net GND/VCC

一般出现这个提示,不是错误.     可以取消net 网格标号 这样就不会报这个警告了。 还可以设置规则,不让它报告。     点击确定,但是再次打开工程时有得警告这个错...
  • zhaocundang
  • zhaocundang
  • 2016年05月23日 09:49
  • 3878

dom4j:Adding text to an XML document must not be null

在使用dom4j组装xml时,出现如下错误: org.apache.cxf.interceptor.Fault: Adding text to an XML document must not be ...
  • zxnlmj
  • zxnlmj
  • 2014年03月30日 14:24
  • 6527
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Adding Dynamic Contents to IFrames
举报原因:
原因补充:

(最多只允许输入30个字)