使用Ajax请求显示进度条进度

28

我希望在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();
   }

1
您可以通过绑定进度事件来获取下载状态。请查看此示例 - https://gist.github.com/nebirhos/3892018 - tusharmath
1
另外,https://github.com/kpozin/jquery-ajaxprogress。 - tusharmath
这里我实现了进度条(http://js-control-files-uploader.itweb-projects.com/),但是我使用 xhr.upload.addEventListener('progress', ... Github: https://github.com/dimitardanailov/js-control-files-uploader/blob/master/javascript/js-control-files-uploader/fileapi.js - d.danailov
5个回答

32

问题在于你不知道请求需要多长时间。

要实现进度条,您需要设置百分比或已完成步骤的数量。

如果您不希望进度条只是从0跳到100,您需要有一种方法在请求完成之前测量完成率。

如果您可以猜测所需的时间,您可以使用计时器自动递增到90%,并在服务器响应后将其设置为100%。当然,这相当虚假。

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

如果请求确实很长,您可以向服务器发送其他请求以查询进度。但这可能会给服务器带来很多工作。

抱歉,但进度条很难实现......


12
那我们最好还是使用经典的预加载GIF图,对吧? - yretuta

3
我没有使用jQuery,但这可能可以帮助你。
这是一个具有虚假回退的动画Ajax进度条。
我只传递了一个虚假大小,知道我的脚本的平均大小。
因此,如果我的脚本大约为50-100kb,则将虚假大小设置为150kb。
如果计算长度不可用,则使用虚假大小。
在此脚本中,我还添加了额外的检查,使得进度条大小始终小于容器。
通过将虚拟大小乘以2来实现..如果它比加载的数据小。
为了使事情看起来好看,我还添加了CSS3过渡效果,使其延迟700ms。
这个动画延迟添加了使进度条看起来真实所需的一切。
复制并粘贴到HTML文件中,并使用像Chrome这样的现代浏览器进行检查。
YOURSITE 替换为ajax内容站点...或其他。
<!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>

你基本上只需要使用jQuery中的progress函数,然后在脚本加载完成时将进度条设置为100%。


3
我在我们公司的内部应用中遇到了这种情况。这是一个关键性的应用程序,我们需要向用户展示进度。因此,尽管@Thilo提到了网络流量问题,但我们必须实现它,以便告知用户长时间运行的过程何时完成以及其进展如何。
我们将其分解成小块来处理。
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. 在你的客户端代码中,使用这个返回的值(计数器)来更新你的进度条。
除了仅计数器外,您还可以返回包含相关详细信息(例如记录ID)的对象,以向用户显示进程当前的位置。
请确保非常小心地处理线程,处理所有可能的异常并进行适当的清理。

1
编辑:为了后人留下我的先前答案,但是由于它实际上并没有回答所提出的问题,我提供了一个新的答案。
一些评论指出了实现此目的的较新方法。由于HTML5和更新的XHR2,可以将回调放在AJAX请求的进度上。这涉及您向XHR对象添加事件侦听器并向适当的属性提供回调。页面具有良好的上传和下载示例,此git存储库看起来很不错,并且最近进行了更新。
此外,如果您真的对XHR和覆盖感兴趣,Mozilla文档应该也会有很大帮助。实际上,这篇文档文章似乎是我提到的git存储库的基础。

旧答案: 对于编写Web应用程序的人来说,这是一个古老的问题,尽管Thilo是正确的,但现在这已经不像以前那么困难了。目前最好的(依我之见)解决方案是将您要上传的文件“分块”,并在每次上传一个块时更新进度条。 此SO问题及其答案是开始理解这个概念甚至如何将其应用于您的情况的好地方。

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

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


我不确定我理解你的问题。一个用户上传一个文件,由你的前端代码抓取。然后你将文件分成块,并一次发送一个块到你的服务器端代码。你可以在任何类型的文件上使用它,并且它允许你知道文件在任何给定时间已上传的百分比。 - David Myers
1
OP 中没有提到上传文件。 - 1983
哇,我刚刚重新读了问题,你说得对。失败了。我会编辑/修订我的答案。 - David Myers

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接