Javascript 显示带有ajax请求的进度条进度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2474528/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:31:33  来源:igfitidea点击:

showing progressbar progress with ajax request

javascriptjquery-uijquery

提问by yretuta

I want to show progress with jquery ui progress bar when an ajax request fires and when it finishes. The problem is I don't know how to set values for the progress bar depending on the progress of the ajax request. Here's a code to start with:

我想在 ajax 请求触发和完成时使用 jquery ui 进度条显示进度。问题是我不知道如何根据 ajax 请求的进度设置进度条的值。这是一个开始的代码:

function ajaxnews()
    {
        $('.newstabs a').click(function(e){
            var section = $(this).attr('id');
            var url = base + 'news/section/' + section;

            $.ajax({
                url : url,
                dataTye : 'html',
                start : loadNews,
                success : fillNews
            });
        });
    }



// start callback functions
   function loadNews()
   {

       $('#progressbar').fadeIn();
       $('#progressbar').progressbar({ //how shoud I set the values here});
   }

   function fillNews()
   {
    $('#progressbar').progressbar('option', 'value', ?? /* how do I find this?*/);   
    $('#progressbar').fadeOut();
   }

回答by Thilo

The fundamental problem is that you do not know how long the request is going to take.

根本问题是您不知道请求需要多长时间。

For the progress bar, you need to set a percentage, or a number of completed steps.

对于进度条,您需要设置一个百分比,或已完成的步骤数。

If you do not want the progress bar to just jump from 0 to 100, you need to have some way to measure the completion rate before the request is finished.

如果你不希望进度条只是从 0 跳到 100,那么你需要有一些方法来衡量请求完成之前的完成率。

If you can guess how long it takes, you could use a timer to have it incrementally advance to, say, 90%, automatically, and when the server response comes it, set it to 100%. Of course, that is faking it quite a bit.

如果你能猜出需要多长时间,你可以使用一个计时器让它自动递增到 90%,当服务器响应到来时,将它设置为 100%。当然,这在很大程度上是假装的。

If you have more than one request, you could use the number of completed requests as a percentage. If it makes sense, you could break down your single request into multiple, but carefully think about the impact this has on network traffic and response times. Don't just do it for the sake of the progress bar.

如果您有多个请求,您可以使用已完成请求的数量作为百分比。如果有意义,您可以将单个请求分解为多个,但请仔细考虑这对网络流量和响应时间的影响。不要只是为了进度条而做。

If the request really takes long, you could fire off additional requests to the server to inquire the progress. But that could mean a lot of work server-side.

如果请求确实需要很长时间,您可以向服务器发出其他请求以查询进度。但这可能意味着服务器端的大量工作。

Sorry, but progress bars are hard...

对不起,但进度条很难...

回答by cocco

i don't use jquery,but this maybe can help you.

我不使用 jquery,但这也许可以帮助你。

It's a Animated Ajax Progress Bar with Fake Fallback.

这是一个带有假回退的动画 Ajax 进度条。

i just pass a fake size knowing the average size of my scripts

我只是通过一个假的大小知道我的脚本的平均大小

so if my scripts are around 50-100kb i set the fake size to 150kb.

因此,如果我的脚本大约为 50-100kb,我会将假大小设置为 150kb。

if the computed length is not available i use the fake size.

如果计算出的长度不可用,我使用假尺寸。

in this script i added also a extra check that the bar size is always smaller than the container.

在这个脚本中,我还添加了一个额外的检查,即条形尺寸总是小于容器。

simply by multiplying the fake-size *2 .. if its smaller than the loaded data.

只需乘以 fake-size *2 .. 如果它小于加载的数据。

to make things look nice i added also a css3 transition effect so that it delays 700ms.

为了让事情看起来不错,我还添加了一个 css3 过渡效果,以便延迟 700 毫秒。

this animation delay adds everything you need to make the progress bar look real.

这个动画延迟添加了使进度条看起来真实所需的一切。

copy & paste into a html file and check with a modern browser like chrome.

复制并粘贴到 html 文件中,然后使用 chrome 等现代浏览器进行检查。

replace YOURSITEwith a ajax content site... or whatever.

用ajax 内容站点替换YOURSITE......或其他任何内容。

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Ajax Progress</title>
<style>
#progress{
 width:300px;
 height:20px;
 border:1px solid rgba(0,0,0,0.5);
}
#bar{
 width:0%;
 height:20px;
 background-color:green;
 -webkit-transition:width 700ms ease;   
}
</style>
<script>
var
pb,
fakeSize=100000,//~100kb
progress=function(e){
 fakeSize=(e.loaded>fakeSize?(fakeSize*2):fakeSize);//Bonus
 var tot=(e.lengthComputable?e.total:fakeSize);
 pb.style.width=(100/tot*e.loaded)+'%';
},
onloaded=function(e){
 pb.style.width='100%';
},
ajax=function(a,c){
 c=new XMLHttpRequest;
 c.open('GET',a);
 c.onprogress=progress;
 c.onload=onloaded;
 c.send()
};
window.onload=function(){
 pb=document.getElementById('bar');
 ajax('YOURSITE');
}
</script>
</head>
<body>
<div id="progress"><div id="bar"></div></div>
</body>
</html>

you basically just need to use the progress function in jquery and then set the bar to 100% when script has loaded.

您基本上只需要在 jquery 中使用进度功能,然后在脚本加载时将栏设置为 100%。

回答by Abhitalks

I faced this situation in our company's in-house app. It was a critical app and we needed to show progress to the user. So, despite the fact that @Thilo mentioned about network traffic, we had to implement it so that the user could be informed when the long running process was finished and how it progressed over time.

我在我们公司的内部应用程序中遇到了这种情况。这是一个关键的应用程序,我们需要向用户展示进度。因此,尽管@Thilo 提到了网络流量,但我们必须实现它,以便用户可以在长时间运行的过程完成时得到通知,以及它如何随着时间的推移而进展。

We broke it down to small pieces.

我们把它分解成小块。

  1. Spawn a thread on the server-side code to run the particular process. For ASP.Net it was like this:

    System.Threading.ThreadPool.QueueUserWorkItem(AddressOf MyProcessRoutine, objectParameter)

  2. Within this "MyProcessRoutine" run your long-running code and update a static variable for counter or persist in database, for each step you want to monitor.

  3. Create another function routine which keeps checking this counter and returns the current value. For example: Public Shared Function CheckStatus() As Integer

  4. From your client-side code keep polling this routine say every 5 seconds (depending on how much network traffic you can afford and how much precision you want. For example: timer = setInterval("MyWebService.CheckStatus();", 500);

  5. In your client-side code, use this returned value (counter) to update your progress bar.

  1. 在服务器端代码上生成一个线程来运行特定进程。对于 ASP.Net,它是这样的:

    System.Threading.ThreadPool.QueueUserWorkItem(AddressOf MyProcessRoutine, objectParameter)

  2. 在这个“ MyProcessRoutine”中运行你的长时间运行的代码,并为你想要监控的每个步骤更新计数器或持久化数据库中的静态变量。

  3. 创建另一个函数例程,它不断检查此计数器并返回当前值。例如:Public Shared Function CheckStatus() As Integer

  4. 从您的客户端代码中,每 5 秒轮询一次此例程(取决于您可以承受多少网络流量以及您想要多少精度。例如: timer = setInterval("MyWebService.CheckStatus();", 500);

  5. 在您的客户端代码中,使用此返回值(计数器)来更新您的进度条。

Besides just a counter, you can also return an object containing relevant details like record-id to show the user about where the process is currently at.

除了只是一个计数器,您还可以返回一个包含相关详细信息的对象,例如记录 ID,以向用户显示进程当前所在的位置。

Make sure you handle the thread very carefully, handle all possible exceptions and have proper cleanup.

确保您非常小心地处理线程,处理所有可能的异常并进行适当的清理。

回答by David Myers

Edit: For posterity I've left my previous answer below, but seeing as how it doesn't actually answer the question being asked I'm providing a new answer.

编辑:对于后人,我已经在下面留下了我以前的答案,但鉴于它实际上并没有回答所提出的问题,我正在提供一个新答案。

Some of the comments on the question have pointed out newer methods of accomplishing this. Thanks to HTML5 and the newer XHR2 it's possible to put callbacks on the progress of AJAX requests. This involves you adding event listeners to the XHR object and providing callbacks to the appropriate properties. Thispage has good examples for both upload and download and this git repolooks good and has been updated recently.

关于这个问题的一些评论指出了实现这一点的新方法。感谢 HTML5 和更新的 XHR2,可以对 AJAX 请求的进度进行回调。这涉及将事件侦听器添加到 XHR 对象并提供对适当属性的回调。这个页面有很好的上传和下载示例,这个 git repo看起来不错,最近已经更新。

Also, if you're really interested in digging into the XHR and overrides, this Mozilla docpost should help out a lot as well. And in fact, this doc post seems to be what the git repo I mentioned was based off of.

此外,如果您真的有兴趣深入研究 XHR 和覆盖,这篇 Mozilla 文档帖子也应该有很大帮助。事实上,这个 doc post 似乎是我提到的 git repo 的基础。

Old Answer: This is an age old problem for people writing web apps and while Thilo was right, this is no longer as difficult as it once was. The best (imo) current solution is to "chunk" the files you're uploading and update your progress bar every time you upload a chunk. This SO questionand it's answer is a good place to start understanding this concept and even how to apply it to your situation.

旧答案:对于编写 Web 应用程序的人来说,这是一个古老的问题,虽然 Thilo 是对的,但这不再像以前那样困难。当前最好的(imo)解决方案是“分块”您正在上传的文件并在每次上传块时更新进度条。这个 SO 问题及其答案是开始理解这个概念甚至如何将其应用于您的情况的好地方。

But suffice it to say, what you'll do is take the file you're uploading and split it up into smaller pieces on the client side. There are several potential benefits to this, but the primary one in this case is that it allows you to know every time a specified percentage of the file has been uploaded to the server. And obviously every time a chunk is uploaded you can update the progress bar accordingly.

但我只想说,您要做的就是将您上传的文件在客户端拆分成更小的部分。这有几个潜在的好处,但在这种情况下主要的好处是它允许您知道每次指定百分比的文件已上传到服务器。显然,每次上传块时,您都可以相应地更新进度条。

Chunking the file like this also allows you to effectively "pause" or "resume" uploads since you can upload different parts of a file at any given time.

像这样将文件分块还可以让您有效地“暂停”或“恢复”上传,因为您可以在任何给定时间上传文件的不同部分。

回答by RayLoveless

This should be possible with server side events

这应该可以通过服务器端事件实现