可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
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 readyState
to check the iframe state:
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 not when the contents are a binary file:
if ($.browser.mozilla || $.browser.webkit ) { iframe.onload = function showProgressAnimation() { animation.style.display = 'none'; progressBar.hide(); $('#page').show(); } } // IE else{ window.setTimeout(showProgressAnimation, 1000); }
回答1:
You can use the onload
to signaling the load of the 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 src
loaded last.
http://jsfiddle.net/48MQW/24/
回答2:
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:
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.
回答3:
Please try this - you are really mixing dom and jQuery from line to line
var tId; function stopAnim() { // I stop the animation and show the page animation.hide(); progressBar.hide(); $('#page').show(); clearInterval(tId); } var 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); //