単純なjavascriptは非常に単純です。コールバックを{XMLHTTPRequest}.onprogress
に添付するだけです
var xhr = new XMLHttpRequest();
xhr.onprogress = function(e){
if (e.lengthComputable)
var percent = (e.loaded / e.total) * 100;
};
xhr.open('GET', 'http://www...', true);
xhr.onreadystatechange = function() {
...
};
xhr.send(null);
しかし、JQuery($.get()
または$.ajax()
)でhtmlデータをダウンロードするajaxサイトをやっています。小さなプログレスバーですが、不思議なことに、私はJQueryのドキュメントで有用なものを見つけていません...
$.ajax
については次のようなもの(HTML5のみ):
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
//Do something with upload progress here
}
}, false);
xhr.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
//Do something with download progress
}
}, false);
return xhr;
},
type: 'POST',
url: "/",
data: {},
success: function(data){
//Do something on success
}
});
jQueryはすでにプロミスを実装しているので、イベントロジックをoptions
パラメーターに移動しないで、このテクノロジーを使用することをお勧めします。プログレスプロミスを追加するjQueryプラグインを作成しましたが、他のプロミスと同じように簡単に使用できるようになりました。
$.ajax(url)
.progress(function(){
/* do some actions */
})
.progressUpload(function(){
/* do something on uploading */
});
github で確認してください
jQueryには AjaxSetup()
関数があり、beforeSend
やcomplete
などのグローバルajaxハンドラーをすべてのajax呼び出しに登録できるほか、xhr
にアクセスできます。あなたが探している進歩をするオブジェクト
Ajaxオブジェクトの構築をインターセプトする3つの異なる方法について試しました。
xhrFields
を使用しましたが、それは1人のリスナーのみを許可し、ダウンロードにのみ接続し(アップロードではなく)、不必要なコピーアンドペーストのように見えるものを必要とします。progress
関数を添付しましたが、ハンドラーの独自の配列を維持する必要がありました。ある場所ではXHRにアクセスし、別の場所ではjQuery XHRにアクセスできるため、ハンドラーをアタッチするための適切なオブジェクトを見つけることができませんでしたが、遅延オブジェクト(その約束のみ)にはアクセスできませんでした。ajax
を自分のものに置き換えました。唯一の潜在的な欠点は、独自のxhr()
設定を使用できなくなることです。 options.xhr
が関数であるかどうかを確認することで、これを許可できます。実際にpromise.progress
関数xhrProgress
を呼び出すので、後で簡単に見つけることができます。アップロードリスナーとダウンロードリスナーを区別するために、別の名前を付けることもできます。元のポスターが必要なものをすでに入手していても、これが誰かの助けになることを願っています。
(function extend_jQuery_ajax_with_progress( window, jQuery, undefined ) {
var $originalAjax = jQuery.ajax;
jQuery.ajax = function (url, options) {
if (typeof(url) === 'object') {
options = url;
url = undefined;
}
options = options || {};
// Instantiate our own.
var xmlHttpReq = $.ajaxSettings.xhr();
// Make it use our own.
options.xhr = function () {
return(xmlHttpReq);
};
var $newDeferred = $.Deferred();
var $oldPromise = $originalAjax(url, options)
.done(function done_wrapper( response, text_status, jqXHR) {
return($newDeferred.resolveWith(this, arguments));
})
.fail(function fail_wrapper(jqXHR, text_status, error) {
return($newDeferred.rejectWith( this, arguments));
})
.progress(function progress_wrapper() {
window.console.warn("Whoa, jQuery started actually using deferred progress to report Ajax progress!");
return($newDeferred.notifyWith( this, arguments));
});
var $newPromise = $newDeferred.promise();
// Extend our own.
$newPromise.progress = function (handler) {
// Download progress
xmlHttpReq.addEventListener('progress', function download_progress(evt) {
// window.console.debug( "download_progress", evt );
handler.apply(this, [evt]);
}, false);
// Upload progress
xmlHttpReq.upload.addEventListener('progress', function upload_progress(evt) {
// window.console.debug( "upload_progress", evt );
handler.apply(this, [evt]);
}, false);
return(this);
};
return($newPromise);
};
})(window, jQuery);