Iframe Tips ABC

通常我们用 js 脚本创建 iframe 时,会这样写:

var iframe = document.createElement('iframe');

之后我们可能会定义 id、name、border 等属性,这些看似简单,其实 IE 与非 IE 浏览器之间、IE 和 IE 高版本之间的迥异,使得 iframe 的相关兼容性操作非常地有文章。

牛A:frameborder

现象:使用 (iframe.frameBorder = 数值) 或(iframe.setAttribute(‘frameborder’,数值)) 在 IE 浏览器下无效
原因:IE 浏览器区分属性名称大小写
解决方法:iframe.setAttribute(‘frameBorder’,’0′) Or iframe.setAttribute(‘frameborder’,’0′,0),兼容所有浏览器。

注:经测试,IE8已经修复此问题

牛B:动态将Form target到iframe

背景:假设现在我们要让一个 Form 表单结果提交到一个 HTML 结构中已存在的 iframe,会这样做:

&lt;form id="form" name="form" target="相应iframe的name:iframeNB" method="post" &gt;<br style="margin: 0px; padding: 0px;" />&lt;/form&gt;<br style="margin: 0px; padding: 0px;" />&lt;iframe name="iframeNB" &gt;&lt;/iframe&gt;

OK,什么问题也没有,再假设我们需要提交到脚本动态生成的 iframe 中,会这样做:

&lt;form id="form" name="form" target="iframeNB" method="post" &gt;<br style="margin: 0px; padding: 0px;" />&lt;/form&gt;<br style="margin: 0px; padding: 0px;" />&lt;script&gt;<br style="margin: 0px; padding: 0px;" />var iframe = document.createElement('iframe');<br style="margin: 0px; padding: 0px;" />iframe.name = 'iframeNB';<br style="margin: 0px; padding: 0px;" />...<br style="margin: 0px; padding: 0px;" />someParent.appendChild(iframe);<br style="margin: 0px; padding: 0px;" />&lt;/script&gt;

去 IE 浏览器里试试,你会发现 Form 会在新窗口显示提交结果,Why?
原因:
我为此尝试了很久,结果是IE此前版本不能通过(iframe.name=)这种方式给 iframe 设置 name 值,也就是说生成的 iframe 是没有 name 值的,但却可以 alert 出来,这很诡异;当然,这也并不是没有解决办法。
解决方法,为此我们得为 IE 单独写一行代码:


  <span style="margin: 0px; padding: 0px; color: gray;">/*only for ie */</span> <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: navy; font-weight: bold;">var</span> iframe = document.createElement(<span style="margin: 0px; padding: 0px; color: teal;">'&lt;iframe name="iframeNB"&gt;'</span>); <br style="margin: 0px; padding: 0px;" />

看到这行代码,我们笑了,这是天大的杯具(喜剧?)~~不管IE有多么搓的问题,他总会有自己一套解决之……
而且这行代码会在其他非 IE 浏览器抛出异常,所以我们可以利用这点来做最终版:


    <span style="margin: 0px; padding: 0px; color: navy; font-weight: bold;">var</span> iframe; <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: navy; font-weight: bold;">try</span><span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">{</span> <br style="margin: 0px; padding: 0px;" />        iframe = document.createElement(<span style="margin: 0px; padding: 0px; color: teal;">'&lt;iframe name="iframeNB"&gt;'</span>); <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">}</span><span style="margin: 0px; padding: 0px; color: navy; font-weight: bold;">catch</span>(e)<span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">{</span> <br style="margin: 0px; padding: 0px;" />        iframe = document.createElement(<span style="margin: 0px; padding: 0px; color: teal;">'iframe'</span>); <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">}</span> <br style="margin: 0px; padding: 0px;" />    iframe.name = <span style="margin: 0px; padding: 0px; color: teal;">'iframeNB'</span>; <br style="margin: 0px; padding: 0px;" />    ... <br style="margin: 0px; padding: 0px;" />    someParent.appendChild(iframe); <br style="margin: 0px; padding: 0px;" />    ... <br style="margin: 0px; padding: 0px;" />

[2009-12-9]补充:最佳实践 – YUI 是如何 creat iframe 的


    <span style="margin: 0px; padding: 0px; color: gray;">/** <br style="margin: 0px; padding: 0px;" />    * @description Creates an iframe to be used for form file uploads.  It is remove from the <br style="margin: 0px; padding: 0px;" />    * document upon completion of the upload transaction. <br style="margin: 0px; padding: 0px;" />    * @method createFrame <br style="margin: 0px; padding: 0px;" />    * @private <br style="margin: 0px; padding: 0px;" />    * @static <br style="margin: 0px; padding: 0px;" />    * @param {string} optional qualified path of iframe resource for SSL in IE. <br style="margin: 0px; padding: 0px;" />    * @return {void} <br style="margin: 0px; padding: 0px;" />    */</span> <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: #4169e1; font-weight: bold;">function</span> _createFrame(secureUri)<span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">{</span> <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: green;">// IE does not allow the setting of id and name attributes as object</span> <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: green;">// properties via createElement().  A different iframe creation</span> <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: green;">// pattern is required for IE.</span> <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: navy; font-weight: bold;">var</span> frameId = <span style="margin: 0px; padding: 0px; color: teal;">'yuiIO'</span> + <span style="margin: 0px; padding: 0px; color: #4169e1; font-weight: bold;">this</span>._transaction_id,io; <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: navy; font-weight: bold;">if</span>(YAHOO.env.ua.ie)<span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">{</span> <br style="margin: 0px; padding: 0px;" />        io = document.createElement(<span style="margin: 0px; padding: 0px; color: teal;">'&lt;iframe id="'</span> + frameId + <span style="margin: 0px; padding: 0px; color: teal;">'"name="'</span> + frameId + <span style="margin: 0px; padding: 0px; color: teal;">'" /&gt;'</span>); <br style="margin: 0px; padding: 0px;" />        <span style="margin: 0px; padding: 0px; color: green;">// IE will throw a security exception in an SSL environment if the</span> <br style="margin: 0px; padding: 0px;" />        <span style="margin: 0px; padding: 0px; color: green;">// iframe source is undefined.</span> <br style="margin: 0px; padding: 0px;" />        <span style="margin: 0px; padding: 0px; color: navy; font-weight: bold;">if</span>(<span style="margin: 0px; padding: 0px; color: #4169e1; font-weight: bold;">typeof</span> secureUri == <span style="margin: 0px; padding: 0px; color: teal;">'boolean'</span>)<span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">{</span> <br style="margin: 0px; padding: 0px;" />            io.src = <span style="margin: 0px; padding: 0px; color: teal;">'javascript:false'</span>; <br style="margin: 0px; padding: 0px;" />        <span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">}</span> <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">}</span><span style="margin: 0px; padding: 0px; color: navy; font-weight: bold;">else</span><span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">{</span> <br style="margin: 0px; padding: 0px;" />        io = document.createElement(<span style="margin: 0px; padding: 0px; color: teal;">'iframe'</span>); <br style="margin: 0px; padding: 0px;" />        io.id = frameId; <br style="margin: 0px; padding: 0px;" />        io.name = frameId; <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">}</span> <br style="margin: 0px; padding: 0px;" />    io.style.position = <span style="margin: 0px; padding: 0px; color: teal;">'absolute'</span>; <br style="margin: 0px; padding: 0px;" />    io.style.top = <span style="margin: 0px; padding: 0px; color: teal;">'-1000px'</span>; <br style="margin: 0px; padding: 0px;" />    io.style.left = <span style="margin: 0px; padding: 0px; color: teal;">'-1000px'</span>; <br style="margin: 0px; padding: 0px;" />    document.body.appendChild(io); <br style="margin: 0px; padding: 0px;" />    YAHOO.log(<span style="margin: 0px; padding: 0px; color: teal;">'File upload iframe created. Id is:'</span> + frameId, <span style="margin: 0px; padding: 0px; color: teal;">'info'</span>, <span style="margin: 0px; padding: 0px; color: teal;">'Connection'</span>); <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">}</span> <br style="margin: 0px; padding: 0px;" />

这里需要额外注意到的一点是:

// IE will throw a security exception in an SSL environment if the<br style="margin: 0px; padding: 0px;" />// iframe source is undefined.<br style="margin: 0px; padding: 0px;" />if(typeof secureUri == 'boolean'){<br style="margin: 0px; padding: 0px;" />io.src = 'javascript:false';<br style="margin: 0px; padding: 0px;" />}

姑且算是牛D吧 =.=!

牛C:iframe.onload

关于 onload 这点大家可以参考怿飞师父的文章:判断 iframe 是否加载完成的完美方法,在此纯引用一次代码:


<span style="margin: 0px; padding: 0px; color: navy; font-weight: bold;">var</span> iframe = document.createElement(<span style="margin: 0px; padding: 0px; color: teal;">"iframe"</span>); <br style="margin: 0px; padding: 0px;" />iframe.src = <span style="margin: 0px; padding: 0px; color: teal;">"http://www.planabc.net"</span>; <br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; color: navy; font-weight: bold;">if</span> (iframe.attachEvent) <span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">{</span> <br style="margin: 0px; padding: 0px;" />    iframe.attachEvent(<span style="margin: 0px; padding: 0px; color: teal;">"onload"</span>, <span style="margin: 0px; padding: 0px; color: #4169e1; font-weight: bold;">function</span> () <span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">{</span> <br style="margin: 0px; padding: 0px;" />        alert(<span style="margin: 0px; padding: 0px; color: teal;">"Local iframe is now loaded."</span>); <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">}</span>); <br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">}</span> <span style="margin: 0px; padding: 0px; color: navy; font-weight: bold;">else</span> <span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">{</span> <br style="margin: 0px; padding: 0px;" />    iframe.onload = <span style="margin: 0px; padding: 0px; color: #4169e1; font-weight: bold;">function</span> () <span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">{</span> <br style="margin: 0px; padding: 0px;" />        alert(<span style="margin: 0px; padding: 0px; color: teal;">"Local iframe is now loaded."</span>); <br style="margin: 0px; padding: 0px;" />    <span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">}</span>; <br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px; color: red; font-weight: bold;">}</span> <br style="margin: 0px; padding: 0px;" />document.body.appendChild(iframe); <br style="margin: 0px; padding: 0px;" />

需要注意到的是:

  • IE8也不支持iframe.onload
  • Opera两者均可,所以使用此方法会绑定前者
  • 即使我们不预设iframe.src = some urls,也会默认执行一次onload事件,可以通过分析 src 规避。

附测试文件:
1.iframe_ie_ugly.html
2.iframe_fixed.html
以上,我认为 ABC 中最牛的就是 B 了,这也是我标题的亮点=.=! 斯密达们认为呢?

上述文字转自 http://blog.silentash.com/2009/12/iframe-tips-abc/,感谢原作者给我提供的巨大帮助。

转载在这里与更多人分享。

Tags:

2 comments

  1. iframe在ie下的加载完成还是有一个onreadystatechange的,也可以判断,就像xhr一样,不过HTML5的增强版XHR已经支持onload了。。

Leave a Reply

Your email address will not be published.

*