Je crée un Iframe à la volée et définit comme URL une page qui télécharge un fichier binaire (xls, doc ...). Pendant le téléchargement des fichiers, je montre une animation. Quand non, je le cache.
Le problème est que Chrome ne sait pas quand les fichiers sont complètement téléchargés, c'est-à-dire lorsque l'iframe est complètement chargé. J'utilise la propriété iframe readyState
pour vérifier l'état de l'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);
}
}
Le résultat est donc une boucle infinie.
J'ai essayé ce qui suit et cela fonctionne dans Firefox et Chrome mais pas lorsque le contenu est un fichier binaire:
if ($.browser.mozilla || $.browser.webkit ) {
iframe.onload = function showProgressAnimation() {
animation.style.display = 'none';
progressBar.hide();
$('#page').show();
}
}
// IE
else{
window.setTimeout(showProgressAnimation, 1000);
}
Vous pouvez utiliser le onload
pour signaler la charge du iframe
voici un exemple simple qui fonctionne
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);
Testé ici:
http://jsfiddle.net/48MQW/5/
Avec src
chargé en dernier.
http://jsfiddle.net/48MQW/24/
Le contenu du fichier téléchargeable ne déclenche pas le gestionnaire d'événements readystatechange ou le gestionnaire d'événements onload. De cette façon, vous pouvez définir un cookie côté serveur ainsi que le contenu du fichier, et côté client vérifier régulièrement ce cookie. Par exemple:
serveur
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);
Bien sûr, vous pouvez utiliser votre framework pour vérifier correctement la valeur du cookie, ce n'est qu'un poc, pas un analyseur de cookie sûr.
Veuillez essayer ceci - vous mélangez vraiment dom et jQuery d'une ligne à l'autre
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); //