如何在生成文件进行下载时显示加载动画? [英] How to display a loading animation while file is generated for download?

查看:60
本文介绍了如何在生成文件进行下载时显示加载动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a web application where the user can generate PDF and PowerPoint files. These files may take some time to generate, so I would like to be able to display a loading animation while it generates. The problem here is that I have no mean to know when the download has started. The animation never goes away.

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

I am aware that it could be possible to generate the file "on the side" and alert the user when the file is ready for download using AJAX, but I prefer "locking" the user while he waits for the download to start.

推荐答案

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

To understand what needs to be done here, let's see what normally happens on this kind of request.


  1. 用户点击按钮来请求文件。

  1. User clicks the button to request the file.

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

The file takes time to generate (the user gets no feedback).

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

The file is finished and starts to be sent to user.

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

What we would like to add is a feedback for the user to know what we are doing... Between step 1 and 2 we need to react to the click, and we need to find a way to detect when step 3 occurred to remove the visual feedback. We will not keep the user informed of the download status, their browser will do it as with any other download, we just want to tell the user that we are working on their request.

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

For the file-generation script to communicate with our requester page's script we will be using cookies, this will assure that we are not browser dependent on events, iframes or the like. After testing multiple solutions this seemed to be the most stable from IE7 to latest mobiles.

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

We will use javascript to display a notification on-screen. I've opted for a simple transparent black overlay on the whole page to prevent the user to interact with other elements of the page as following a link might make him loose the possibility to receive the file.

$('#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;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <div id="fader"></div>

  <a href="#path-to-file-generator" id="downloadLink">Click me to receive file!</a>
</body>

简单部分已完成,现在我们需要通知javascript文件正在下载。当文件发送到浏览器时,它会与通常的HTTP标头一起发送,这允许我们更新客户端cookie。我们将利用此功能提供适当的视觉反馈。让我们修改上面的代码,我们需要设置cookie的起始值,并听取它的修改。

The easy part is done, now we need to notify javascript that the file is being downloaded. When a file is sent to the browser, it is sent with the usual HTTP headers, this allows us to update the client cookies. We will leverage this feature to provide the proper visual feedback. Let's modify the code above, we will need to set the cookie's starting value, and listen to it's modifications.

var setCookie = function(name, value, expiracy) {
  var exdate = new Date();
  exdate.setTime(exdate.getTime() + expiracy * 1000);
  var c_value = escape(value) + ((expiracy == null) ? "" : "; expires=" + exdate.toUTCString());
  document.cookie = name + "=" + c_value + '; path=/';
};

var getCookie = function(name) {
  var i, x, y, ARRcookies = document.cookie.split(";");
  for (i = 0; i < ARRcookies.length; i++) {
    x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("="));
    y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1);
    x = x.replace(/^\s+|\s+$/g, "");
    if (x == name) {
      return y ? decodeURI(unescape(y.replace(/\+/g, ' '))) : y; //;//unescape(decodeURI(y));
    }
  }
};

$('#downloadLink').click(function() {
  $('#fader').css('display', 'block');
  setCookie('downloadStarted', 0, 100); //Expiration could be anything... As long as we reset the value
  setTimeout(checkDownloadCookie, 1000); //Initiate the loop to check the cookie.
});
var downloadTimeout;
var checkDownloadCookie = function() {
  if (getCookie("downloadStarted") == 1) {
    setCookie("downloadStarted", "false", 100); //Expiration could be anything... As long as we reset the value
    $('#fader').css('display', 'none');
  } else {
    downloadTimeout = setTimeout(checkDownloadCookie, 1000); //Re-run this function in 1 second.
  }
};

#fader {
  opacity: 0.5;
  background: black;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: none;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <div id="fader"></div>

  <a href="#path-to-file-generator" id="downloadLink">Click me to receive file!</a>
</body>

好的,我们在这里添加了什么。我已经使用了我使用的set / getCookie函数,我不知道它们是否是最好的,但是它们的效果非常好。我们在启动下载时将cookie值设置为0,这将确保任何其他过去的执行都不会干扰。我们还启动超时循环来每秒检查cookie的值。这是代码中最有争议的部分,使用超时循环函数调用等待cookie更改发生可能不是最好的,但它是在所有浏览器上实现此功能的最简单方法。因此,我们每秒检查一次cookie值,如果值设置为1,我们会隐藏褪色的视觉效果。

Ok, what have we added here. I've put the set/getCookie functions I use, I don't know if they are the best, but they work very well. We set the cookie value to 0 when we initiate the download, this will make sure that any other past executions will not interfere. We also initiate a "timeout loop" to check the value of the cookie every second. This is the most arguable part of the code, using a timeout to loop function calls waiting for the cookie change to happen may not be the best, but it has been the easiest way to implement this on all browsers. So, every second we check the cookie value and, if the value is set to 1 we hide the faded visual effect.

在PHP中,人们会这样做:

In PHP, one would do like so:

setCookie("downloadStarted", 1, time() + 20, '/', "", false, false);

在ASP.Net中

Response.Cookies.Add(new HttpCookie("downloadStarted", "1") { Expires = DateTime.Now.AddSeconds(20) });

cookie的名称是 downloadStarted ,其值是 1 ,它在 NOW + 20秒过期(我们每秒检查一次,所以20对于那个来说已经足够了,如果更改javascript中的超时值,则更改此值,其路径在整个域上(根据您的喜好进行更改),因为它不包含敏感数据而且不是HTTP,所以我们的javascript可以看到它,因此不安全。

Name of the cookie is downloadStarted, its value is 1, it expires in NOW + 20seconds (we check every second so 20 is more than enough for that, change this value if you change the timeout value in the javascript), its path is on the whole domain (change this to your liking), its not secured as it contains no sensitive data and it is NOT HTTP only so our javascript can see it.

Voilà!总结一下。请注意,所提供的代码完全适用于我正在使用的生产应用程序,但可能不符合您的确切需求,请根据您的喜好进行更正。

Voilà! That sums it up. Please note that the code provided works perfectly on a production application I am working with but might not suit your exact needs, correct it to your taste.

这篇关于如何在生成文件进行下载时显示加载动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆