Javascript Iframe.readyState 在 chrome 中不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13952942/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Iframe.readyState does not work in chrome
提问by anmarti
I create an Iframe on the fly and set as the url a page that downloads a binary file (xls, doc...).While files are downloading I show an animation. When does not, I hide it.
我即时创建了一个 Iframe,并将下载二进制文件(xls、doc ...)的页面设置为 url 。在下载文件时,我会播放动画。什么时候没有,我隐藏它。
The problem is that Chrome does not know when the files are fully downloaded, that is when the iframe is completely loaded. I use the iframe property readyStateto check the iframe state:
问题是 Chrome 不知道文件何时完全下载,即 iframe 何时完全加载。我使用 iframe 属性readyState来检查 iframe 状态:
var iframe = document.createElement("iframe");
iframe.style.visibility = "hidden";
// I start a progress animation
window.setTimeout(showProgressAnimation, 1000);
// I start the file download
iframe.src ='GetFile.aspx?file=' + fileName;
document.body.appendChild(iframe);
function showProgressAnimation() {
if (iframe.readyState == "complete" || iframe.readyState == "interactive") {
// I stop the animation and show the page
animation.style.display = 'none';
progressBar.hide();
$('#page').show();
}
else {
// Chrome is always getting into this line
window.setTimeout(showProgressAnimation, 1000);
}
}
So the result is an infinite loop.
所以结果是无限循环。
I've tried the following and it works in Firefox and Chrome but notwhen the contents are a binary file:
我尝试了以下方法,它在 Firefox 和 Chrome 中有效,但在内容是二进制文件时无效:
if ($.browser.mozilla || $.browser.webkit ) {
iframe.onload = function showProgressAnimation() {
animation.style.display = 'none';
progressBar.hide();
$('#page').show();
}
}
// IE
else{
window.setTimeout(showProgressAnimation, 1000);
}
采纳答案by Aristos
You can use the onloadto signaling the load of the iframe
您可以使用onload来指示负载的iframe
here is a simple example that working
这是一个简单的例子,可以工作
var iframe = document.createElement("iframe");
iframe.style.display = "none";
// this function will called when the iframe loaded
iframe.onload = function (){
iframe.style.display = "block";
alert("loaded");
};
// set the src last.
iframe.src ='http://www.test.com';
// add it to the page.
document.getElementById("one").appendChild(iframe);
Tested here:
http://jsfiddle.net/48MQW/5/
With srcloaded last.
http://jsfiddle.net/48MQW/24/
这里测试:
http://jsfiddle.net/48MQW/5/
随着src最后加载。
http://jsfiddle.net/48MQW/24/
回答by sarkiroka
The downloadable file content doesn't trigger the readystatechange event handler or the onload event handler. This couse you can set a cookie in server side together the file content, and client side check this cookie periodically. For example:
可下载的文件内容不会触发 readystatechange 事件处理程序或 onload 事件处理程序。这个原因你可以在服务器端设置一个 cookie 和文件内容一起,客户端会定期检查这个 cookie。例如:
server
服务器
response.cookie('fileDownloaded','true');
response.header('attachment','your-file-name.any');
//...write bytes to response...
client
客户
var checker = setInterval(()=>{
if(document.cookie.indexOf('fileDownloaded')>-1){
alert('done');
clearInterval(checker);
}
},100);
Of course, you can use your framework to check the cookie value correctly, this is just a poc, not a safe cookie parser.
当然,您可以使用您的框架正确检查 cookie 值,这只是一个 poc,而不是安全的 cookie 解析器。
回答by mplungjan
Please try this - you are really mixing dom and jQuery from line to line
请试试这个——你真的是在一行一行地混合 dom 和 jQuery
var tId;
function stopAnim() {
// I stop the animation and show the page
animation.hide();
progressBar.hide();
$('#page').show();
clearInterval(tId);
}
var iframe = $("<iframe />");
iframe.css("visibility","hidden");
iframe.on("readystatechange",function() {
if (this.readyState == "complete" || this.readyState == "interactive") {
stopAnim();
}
});
iframe.on("load",function() { // can possibly be deleted
if (tId) {
stopAnim();
}
});
iframe.attr("src","GetFile.aspx?file=" + fileName);
$("body").append(iframe);
tId = setInterval(function() {
// update progress here
}, 1000); //

