7

I'm trying to detect when any ajax call finishes in my UIWebView. I modified the code in this answer: JavaScript detect an AJAX event to the best of my abilities. Here is my attempt:

var s_ajaxListener = new Object();
s_ajaxListener.tempOnReadyStateChange = XMLHttpRequest.prototype.onreadystatechange;
s_ajaxListener.callback = function () {
    window.location='ajaxHandler://' + this.url;
};

XMLHttpRequest.prototype.onreadystatechange = function() {
    alert("onreadystatechange called");
    s_ajaxListener.tempOnReadyStateChange.apply(this, arguments);
    if(s_ajaxListener.readyState == 4 && s_ajaxListener.status == 200) {
        s_ajaxListener.callback();
    }
}

I'm injecting this into the webView but the alert is never firing. If I place an alert at the beginning or end of the script, it'll fire so I'm fairly certain there are no syntax errors.

I'm not a JS guy so I'm hoping this is a trivial problem.

Community
  • 1
  • 1
Lance
  • 8,872
  • 2
  • 36
  • 47
  • Try inverting the order of operations: first define `XMLHttpRequest.prototype.onreadystatechange`, then assign a reference to `s_ajaxListener.tempOnReadyStateChange`. – bfavaretto Sep 24 '13 at 16:31
  • @bfavaretto no beans. – Lance Sep 24 '13 at 16:37
  • @bfavaretto maybe I didn't understand completely though, could you post a code example in an answer? – Lance Sep 24 '13 at 16:38
  • I'm realizing there may be more to it, I'll do some tests first. – bfavaretto Sep 24 '13 at 16:44
  • @Lance did you get this figured out? If so can you share your answer? – Bot Apr 08 '14 at 15:52
  • @Bot never got this to work reliably. Ended up solving my problem by injecting a CSS rule into the HTML. – Lance Apr 08 '14 at 16:09
  • @Lance I am wanting to know when googles ajax search results are done in my uiwebview. Would your CSS rule help me? – Bot Apr 08 '14 at 16:17
  • @Bot I was trying to detect when a banner was added and hide it. I just used CSS to hide the banner no matter when it appeared. Doesn't sound like that is your goal. :( – Lance Apr 08 '14 at 19:32

1 Answers1

4

Putting a generic onreadystatechange in XMLHttpRequest.prototype didn't work for me. However the code you linked to can be easily adapted to invoke a custom function whenever that event occurs:

var s_ajaxListener = {};
s_ajaxListener.tempOpen = XMLHttpRequest.prototype.open;
s_ajaxListener.tempSend = XMLHttpRequest.prototype.send;
// callback will be invoked on readystatechange
s_ajaxListener.callback = function () {
    // "this" will be the XHR object
    // it will contain status and readystate
    console.log(this);
}

XMLHttpRequest.prototype.open = function(a,b) {
  if (!a) var a='';
  if (!b) var b='';
  s_ajaxListener.tempOpen.apply(this, arguments);
  s_ajaxListener.method = a;  
  s_ajaxListener.url = b;
  if (a.toLowerCase() == 'get') {
    s_ajaxListener.data = b.split('?');
    s_ajaxListener.data = s_ajaxListener.data[1];
  }
}

XMLHttpRequest.prototype.send = function(a,b) {
  if (!a) var a='';
  if (!b) var b='';
  s_ajaxListener.tempSend.apply(this, arguments);
  if(s_ajaxListener.method.toLowerCase() == 'post')s_ajaxListener.data = a;
  // assigning callback to onreadystatechange
  // instead of calling directly
  this.onreadystatechange = s_ajaxListener.callback;
}

http://jsfiddle.net/s6xqu/

bfavaretto
  • 71,580
  • 16
  • 111
  • 150