I need to addEventListener to listen for progress event before opening the XMLHttp connection (i.e. xhr.open()), but          
        
You can override the xhr function in ajaxSetup or even on each individual $.ajax call. This is documented in the $.ajax docs (thanks Nick!).
Your code might look like this (untested) if you want to do this all the time:
(function() {
    var originalXhr = jQuery.ajaxSettings.xhr; 
    jQuery.ajaxSetup({
        xhr: function() {
            var req = originalXhr();
            if (req) {
                // Add your progress handler
            }
            return req;
        }
    });
})();
...or like this (live example) for just a particular request:
$.ajax({
  url: "path/to/resource",
  xhr: function() {
    var req = $.ajaxSettings.xhr();
    if (req) {
      // Add your handler here
    }
    return req;
  }
});
Unfortunately, although overriding xhr is documented, the location of the currently-configured one (jQuery.ajaxSettings.xhr) doesn't seem to be, so technically you're still relying on an undocumented feature by using jQuery.ajaxSettings.xhr in your code. You just need to double-check that that's still there on each dot release, it's probably not going to move around too much (and jQuery.ajaxSettings is at least mentioned in the docs, here).