我是FE,也是Fe

前端来源于不断的点滴积累。我一直在努力。

统计

留言簿(15)

阅读排行榜

评论排行榜

iframe的readyState

最开始让我去研究这个问题是因为最近在做Excel数据导出时碰到的一个问题。导出Excel的基本做法是请求servlet生成一个Excel下载。由于是请求了一个不可见的iframe,所以整个请求过程一直到提示文件下载,除了能看见进度条在跑之外页面几乎没有任何反应,所以我想是不是可以做一个简单的提示正在下载文件之类的。做这个提示的关键就在于捕捉iframe的状态。

最开始大家都会想到用iframe的onload事件去判断iframe是否加载完毕。代码可能会这么写

<iframe id="f" src="demo.docx" style="display:none" onload ="iframe_onload()"  ></iframe>
但是事实上文件下载的iframe有别于contentType为text/plain的iframe。

在IE,Opera,Chrome下onload并没有执行iframe_onload。
在Firefox下可以执行。执行的顺序是先执行iframe_onload,然后再提示文件下载。

上面的小小挫折让我又想到了IE的onreadystatechange事件,代码写成这样:
<iframe id="f" src="demo.docx" style="display:none" border="0" onload ="iframe_onload()" onreadystatechange="iframe_readystatechange();"></iframe>
javascript方法:
        function iframe_onload (){
            alert(
"done.");
        }
        
function iframe_readystatechange(){//IE works
            alert(document.getElementById("f").readyState);//interactive [prompt download file] complete
        }
有趣的是,IE执行的顺序是interavtive ,提示文件下载,complete。

有必要看看readyState的定义了。
readyState的五种状态详解

readyState有五种可能的值:
0 (未初始化): (XMLHttpRequest)对象已经创建,但还没有调用open()方法。
1 (载入):已经调用open() 方法,但尚未发送请求。
2 (载入完成): 请求已经发送完成。
3 (交互):可以接收到部分响应数据。
4 (完成):已经接收到了全部数据,并且连接已经关闭。


The state of the request. The five possible values are 0 = uninitialized, 1 = loading, 2 = loaded, 3 = interactive, and 4 = complete。

可以看出IE能捕捉到下载文件的iframe的interactive状态和complete状态。而且可以看出提示文件下载是在http请求的interactive也就是浏览器交互阶段。

如果把iframe中的src换成一个普通的URL。看到的提示是interactive->complete->loaded。这说明iframe的onload是在http请求的complete之后触发。而且在interactive和complete阶段,可以通过contentWindow.document访问到iframe中的DOM元素(当然,跨域还是不行的,跟ajax一样)。

在interactive阶段能访问到iframe的document。但是按照interactive的定义,正在处理相应数据,可以认为浏览器还在渲染请求到的HTML。渲染没有完毕,应该是不能访问的到iframe中的DOM元素的。

不管怎样,我倒是曾经利用onreadystate的方法改造过IE only的弹出iframe,大家知道用window.open弹出的窗口可以用window.close关闭的。但是如果弹出的iframe层也想用window.close()关闭,基本思路是在iframe的onload时重写iframe的close方法来关闭iframe。这样原来使用window.open打开的页面的代码就不需要修改了。实际上做的时候发现了这么个问题。就是如果window.open方法弹出的页面只有一个<script>window.close()</script>的话。iframe还是不能关闭。这时候可以在iframe的interactive就把iframe.close方法重写。这样,还是可以使用window.close方法关闭弹出层。

总之,利用iframe的onreadystatechange可以做很多的事情,遗憾的是,只有IE能做到这样的效果,其他浏览器iframe没有readyState属性。到目前为止,也没有发现能替代该属性的做法。由于不能兼容其他浏览器,请求隐藏iframe下载文件也变成了在新浏览器窗口下载Excel文件,但是这个过程加深了我对readyState的理解。

介绍一篇文章:
跨浏览器的iframe onload 事件监听

posted on 2010-12-12 16:34 衡锋 阅读(5875) 评论(1)  编辑  收藏 所属分类: javascriptWeb开发

评论

# re: iframe的readyState 2011-09-20 08:35 tb

恩 不错   回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: