我有一个简单的表单,当通过ajax请求提交验证时。如果表单检出正常,则进行另一个ajax请求以处理最初提交的数据。
我想为此构建一个进度条。我发现将此代码添加到每个ajax请求会分别返回每个调用的进度。这使得进度条加载到100%,快速加载两次。
例如,每个填充50%进度条的两个ajax请求是否可能?...所以ajax请求1将填充高达50%,第二个将填充51%到100%?还是那么疯狂?
或者,如果三个ajax调用每个负责占总百分比的33.33%?
我想我们更关注完成阶段和进展。
任何想法如何在没有太多假装的情况下实现这一目标?
var xhr = new window.XMLHttpRequest();
//Upload progress
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
//Do something with upload progress
console.log('percent uploaded: ' + (percentComplete * 100));
}
}, false);
//Download progress
xhr.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
//Do something with download progress
console.log('percent downloaded: ' + (percentComplete * 100));
}
}, false);
return xhr;
答案 0 :(得分:1)
我创建这样一个进度条的方式是,因为你希望一个接一个地调用你的每个函数,即完成一个应该触发另一个,XMLHttpRequest有onreadystate change事件。您可以使用该事件确认第一个请求是否成功执行,然后触发第二个请求,在每次更改时,您将按进度条增加任意%。
function postdata()
{
var xhr = new XMLHttpRequest();
xhr.open
(
"POST",
Url,
true
);
xhr.send();
xhr.onreadystatechange = function()
{
if (xhr.readyState == 4)
{
//Call next function here and increment progressbar
}
}
}
希望这会有所帮助
答案 1 :(得分:0)
是的,有可能。您可以创建包含每个ajax调用的数组。将<progress>
元素max
属性设置为100/array.length
。按类别evt.loaded / evt.total
划分个别progress
事件的.length
以设置value
元素的<progress>
。您还可以使用Promise.all()
,.then()
来处理从ajax调用返回Promise
并更新<progress>
元素的函数数组。
HTML
<label></label>
<progress value="0" min="0" max="100"></progress>
的javascript
var progress = document.querySelector("progress");
var url = "/echo/html/";
function request(url) {
var len = arr.length;
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = ((evt.loaded / evt.total) * (progress.max / len))
/ len;
progress.value += percentComplete;
console.log(progress.value, percentComplete);
if (evt.total === evt.loaded) {
requests += 1;
}
if (progress.value == progress.max && requests === len) {
progress.previousElementSibling.innerHTML = "upload complete";
// you could call `resolve()` here if only interested in
// `upload` portion of request
alert("upload complete");
}
}
}, false);
xhr.onload = function() {
resolve(this.responseText)
};
xhr.onerror = reject;
xhr.open("POST", url, true)
xhr.send("html=" + Array(100000).fill(1).join(""));
})
}
var arr = [], requests = 0;
arr.push(request, request, request);
Promise.all(arr.map(function(req) {
return req(url)
}))
.then(function(data) {
console.log(data);
})
.catch(function(err) {
console.log(err)
})
jsfiddle https://jsfiddle.net/v2msL7hj/3/