生成文件进行下载时如何显示加载动画?

我有一个Web应用程序,用户可以在其中生成PDF和PowerPoint文件。 这些文件可能需要一些时间才能生成,因此我希望能够在生成时显示加载动画。 这里的问题是我无意知道下载何时开始。 动画永远不会消失。

我知道有可能在“侧面”生成文件并在文件准备好使用AJAX下载时提醒用户,但我更喜欢在用户等待下载开始时“锁定”用户。

要了解这里需要做什么,让我们看看这种请求通常会发生什么。

  1. 用户单击该按钮以请求该文件。

  2. 该文件需要时间生成(用户没有反馈)。

  3. 文件已完成并开始发送给用户。

我们想要添加的是反馈,让用户知道我们在做什么……在第1步和第2步之间,我们需要对点击作出反应,我们需要找到一种方法来检测何时发生第3步以删除视觉反馈。 我们不会让用户知道下载状态,他们的浏览器会像其他任何下载一样,我们只是想告诉用户我们正在处理他们的请求。

为了使文件生成脚本与我们的请求者页面的脚本进行通信,我们将使用cookie,这将确保我们不依赖于事件,iframe等浏览器。 在测试了多个解决方案之后,从IE7到最新的移动设备,这似乎是最稳定的。

步骤1.5:显示图形反馈。

我们将使用javascript在屏幕上显示通知。 我在整个页面上选择了一个简单的透明黑色覆盖,以防止用户与页面的其他元素进行交互,因为以下链接可能会使他失去接收文件的可能性。

$('#downloadLink').click(function() { $('#fader').css('display', 'block'); }); 
 #fader { opacity: 0.5; background: black; position: fixed; top: 0; right: 0; bottom: 0; left: 0; display: none; } 
   
Click me to receive file!

您可以使用ajax add indicator获取文件,然后使用dataURI创建标记并使用JavaScript单击它:

您将需要此lib的帮助: https : //github.com/henrya/js-jquery/tree/master/BinaryTransport

 var link = document.createElement('a'); if (link.download != undefined) { $('.download').each(function() { var self = $(this); self.click(function() { $('.indicator').show(); var href = self.attr('href'); $.get(href, function(file) { var dataURI = 'data:application/octet-stream;base64,' + btoa(file); var fname = self.data('filename'); $('' + fname +'').attr({ download: fname, href: dataURI })[0].click(); $('.indicator').hide(); }, 'binary'); return false; }); }); } 

您可以在caniuse上看到下载属性支持

并在你的HTML中把这个:

 generate 

这是Salketer优秀答案的简化版本。 它只是检查cookie的存在,而不考虑它的价值。

在表单提交后,它将每秒轮询cookie的存在。 如果cookie存在,则仍在处理下载。 如果没有,则下载完成。 超时有2分钟。

HTML / JS页面:

 var downloadTimer; // reference to timer object function startDownloadChecker(buttonId, imageId, timeout) { var cookieName = "DownloadCompleteChecker"; var downloadTimerAttempts = timeout; // seconds setCookie(cookieName, 0, downloadTimerAttempts); // set timer to check for cookie every second downloadTimer = window.setInterval(function () { var cookie = getCookie(cookieName); // if cookie doesn't exist, or attempts have expired, re-enable form if ((typeof cookie === 'undefined') || (downloadTimerAttempts == 0)) { $("#" + buttonId).removeAttr("disabled"); $("#" + imageId).hide(); window.clearInterval(downloadTimer); expireCookie(cookieName); } downloadTimerAttempts--; }, 1000); } // form submit event $("#btnSubmit").click(function () { $(this).attr("disabled", "disabled"); // disable form submit button $("#imgLoading").show(); // show loading animation startDownloadChecker("btnSubmit", "imgLoading", 120); }); 
...fields...

支持Javascript设置/获取/删除cookie:

 function setCookie(name, value, expiresInSeconds) { var exdate = new Date(); exdate.setTime(exdate.getTime() + expiresInSeconds * 1000); var c_value = escape(value) + ((expiresInSeconds == null) ? "" : "; expires=" + exdate.toUTCString()); document.cookie = name + "=" + c_value + '; path=/'; }; function getCookie(name) { var parts = document.cookie.split(name + "="); if (parts.length == 2) return parts.pop().split(";").shift(); } function expireCookie(name) { document.cookie = encodeURIComponent(name) + "=; path=/; expires=" + new Date(0).toUTCString(); } 

ASP.Net中的服务器端代码:

 ...generate big document... // attach expired cookie to response to signal download is complete var cookie = new HttpCookie("DownloadCompleteChecker"); // same cookie name as above! cookie.Expires = DateTime.Now.AddDays(-1d); // expires yesterday HttpContext.Current.Response.Cookies.Add(cookie); // Add cookie to response headers HttpContext.Current.Response.Flush(); // send response 

希望有所帮助! 🙂