Skip to content

Instantly share code, notes, and snippets.

@db
Created May 11, 2011 12:43
Show Gist options
  • Save db/966388 to your computer and use it in GitHub Desktop.
Save db/966388 to your computer and use it in GitHub Desktop.
add XHR2 progress events to jQuery.ajax
(function addXhrProgressEvent($) {
var originalXhr = $.ajaxSettings.xhr;
$.ajaxSetup({
progress: function() { console.log("standard progress callback"); },
xhr: function() {
var req = originalXhr(), that = this;
if (req) {
if (typeof req.addEventListener == "function") {
req.addEventListener("progress", function(evt) {
that.progress(evt);
},false);
}
}
return req;
}
});
})(jQuery);
// usage:
// note, if testing locally, size of file needs to be large enough
// to allow time for events to fire
$.ajax({
url: "./json.js",
type: "GET",
dataType: "json",
complete: function() { console.log("Completed."); },
progress: function(evt) {
if (evt.lengthComputable) {
console.log("Loaded " + parseInt( (evt.loaded / evt.total * 100), 10) + "%");
}
else {
console.log("Length not computable.");
}
}
});
@shinuza
Copy link

shinuza commented Jun 9, 2013

You could also use xhrFields

$.ajax({
  url: '/foobar',
  xhrFields: {
    onprogress: function(e) {
        if (evt.lengthComputable) {
            console.log("Loaded " + Number( (e.loaded / e.total * 100)) + "%");
        }
        else {
            console.log("Length not computable.");
        }
    }
  }
});

@yckart
Copy link

yckart commented Oct 12, 2013

+@shinuza

evt should be e (and there's no need for Number here):

$.ajax({
    url: '/foobar',
    xhrFields: {
        onprogress: function (e) {
            if (e.lengthComputable) {
                console.log('Loaded '+ (e.loaded / e.total * 100) + '%');
            } else {
                console.log('Length not computable.');
            }
        }
    }
});

@tr4n2uil
Copy link

For progress events specific to uploading, maybe following change is needed on line #7, #8 and #9

(function addXhrProgressEvent($) {
    var originalXhr = $.ajaxSettings.xhr;
    $.ajaxSetup({
        progress: function() { console.log("standard progress callback"); },
        progressUpload: function() { console.log("standard upload progress callback"); },
        xhr: function() {
            var req = originalXhr(), that = this;
            if (req.upload) {
                if (typeof req.upload.addEventListener == "function") {
                    req.upload.addEventListener("progress", function(evt) {
                        that.progressUpload(evt);
                    },false);
                }
            }
            return req;
        }
    });
})(jQuery);

@AbwR-off
Copy link

AbwR-off commented Feb 8, 2014

I want to do this for progress bar.How can I do this.Cna you write codes?

@dasi1va
Copy link

dasi1va commented Mar 10, 2014

how can I preload percentage html page with ajax and jquery?

@susamcsx
Copy link

susamcsx commented May 4, 2014

hi,i test your code ,but i find that the code "console.log("Loaded " + parseInt( (evt.loaded / evt.total * 100), 10) + "%");" just only log one time,it just print out "100%" only.how can i do?

@ericrange
Copy link

@susamcsx your file is to small!

@manishjodhpur
Copy link

Agree with susamcsx.
It works very fyn in mozzila, but in chrome, it instantly reaches to 100% no matter what file size is
if file is very large, even at that time it reached to 100 instantly.
Please help me to get out this situation, i am almost stuck now with problem from last 3 hours

@SleepWalker
Copy link

added support for the global ajax events

(function addXhrProgressEvent($) {
    var originalXhr = $.ajaxSettings.xhr;

    $.ajaxSetup({
        progress: $.noop,
        xhr: function() {
            var xhr = originalXhr(), that = this;
            if (xhr) {
                if (typeof xhr.addEventListener == "function") {
                    xhr.addEventListener("progress", function(event) {
                        that.progress(event);

                        if (that.global) {
                            var event = $.Event('ajaxProgress', event);
                            event.type = 'ajaxProgress';
                            $(document).trigger(event, [xhr]);
                        }
                    },false);
                }
            }
            return xhr;
        }
    });
})(jQuery);

the problem is that it can be more than one request at a time, so the only one possibility is try to use xhr.responseURL to indentify the requests

@kosso
Copy link

kosso commented Mar 9, 2015

Hi,
Really useful patch. Thanks!

But how can I detect if this patch has already been applied in another js script on a page?
eg: I might have two plugins which included this patch. The second time this is included, it seems to break it.

Cheers!

@kelvinpalves
Copy link

Muito Bom!

@likerRr
Copy link

likerRr commented Aug 28, 2015

I made a plugin, that adds support of progress promise

Copy link

ghost commented Sep 29, 2015

Please how use it ?

@shahzadthathal
Copy link

shahzadthathal commented Apr 20, 2017

Hi,

What does it mean? " Length not computable."
How will it work in jquery-3.1.1?

Thanks

@zalaks
Copy link

zalaks commented May 9, 2018

Not working for me on cpanel server :-(

I have tried with exactly what u have given. However, this worked in localhost !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment