views:

633

answers:

3

When mousing over an image in a jcarousel, my site displays a popup whose contents are loaded via ajax. I'm doing what I thought was fairly straightforward; keeping a handle to the xhrRequest object, and aborting the existing one before making a new request.

It works great in all browsers except IE, where I receive an error "Object doesn't support this property or method"

Here's the code that is triggering it:

function showPopup {
  // ... code snipped ...

  // cancel the existing xhr request
  if (showPopup.xhrRequest != null) {
    showPopup.xhrRequest.abort();
    showPopup.xhrRequest = null;
  }

  showPopup.xhrRequest = $.ajax({url: url, 
                                 type: "GET",
                                 success:function(data) {
                                   $("#popup-content").html(data);
                                 }
                                });

  // ... code snipped ...
}
showPopup.xhrRequest = null;

Works great in Firefox and Chrome. I traced the error down to this bit of code in jquery.js inside the ajax function (line 5233 in my copy of jQuery):

// Override the abort handler, if we can (IE doesn't allow it, but that's OK)
// Opera doesn't fire onreadystatechange at all on abort
try {
  var oldAbort = xhr.abort;
  xhr.abort = function() {
    if (xhr ) {
      oldAbort.call( xhr );
    }

  onreadystatechange( "abort" );
} catch(e) { }

The specific error occurs on the oldAbort.call( xhr ) line. Any ideas?

A: 

The problem is that the XMLHttpRequest object provided by jQuery for Internet Explorer defaults to the COM implementation, not the native window.XMLHttpRequest object, and its methods cannot be overridden.

Also, in the same scenario the abort method is not a Javascript function, so it will not have a prototype and the call method. abort is not available at all on the ActiveX implementations as it was introduced with the native XMLHttpRequest object in IE7.

The native XMLHttpRequest was introduced in IE7, so what you're trying to do would never work in IE6 and it wouldn't work for some users in IE7/IE8 if they have native XMLHttpRequest disabled in their settings (and I've come across this issue before).

You can change the default in jQuery using the xhr option of $.ajax() or $.ajaxSetup():

xhr
Callback for creating the XMLHttpRequest object. Defaults to the ActiveXObject when available (IE), the XMLHttpRequest otherwise. Override to provide your own implementation for XMLHttpRequest or enhancements to the factory.

(emphasis mine)

Andy E
Is there some standard jQuery constructor function I can use that will support abort? If there's no way around this in IE, is there a function I can use that will at least fail silently?Thanks!
Rob Crowell
@Rob Crowell: I didn't notice this before, but the `abort()` method was introduced in IE7, so it doesn't exist in the ActiveX implementations. You could have it fail silently by wrapping a try/catch around it, I suppose.
Andy E
+3  A: 

Found the answer to this on the jquery forums. See discussion here: http://forum.jquery.com/topic/object-doesn-t-support-this-property-or-method-from-jquery-1-4-1-in-ie7-only

The workaround for IE7 and below:

$.ajax({
    ...
    xhr: function() {
        if ($.browser.msie && $.browser.version.substr(0,1) <= 7)
            return new ActiveXObject("Microsoft.XMLHTTP");
        else
            return new XMLHttpRequest();
    },
    ...
});
Rob Crowell
A: 

thanks! you saved me!

kkudi