2013-12-19 3 views
4

Я пытаюсь воспроизвести функции jQuery ajaxComplete и ajaxStart без jQuery, чтобы они могли использоваться в любой среде без каких-либо зависимостей библиотеки (это специальный прецедент). Эти функции позволяют вызывать прослушиватель событий до и после любого запроса ajax. В моем примере я называю их preAjaxListener и postAjaxListener.Воспроизведение функции ajaxStart jQuery и функции ajaxComplete

Я пытаюсь выполнить его, подключившись к объекту XMLHttpRequest и переписав/украсив open и send. Да, я знаю, что это грязно.

XMLHttpRequest.prototype.open = (function(orig){ 
    return function(a,b,c){ 
     this._HREF = b; // store target url 
     return orig.apply(this, arguments); // call original 'open' function 
    }; 
})(XMLHttpRequest.prototype.open); 

XMLHttpRequest.prototype.send = (function(orig){ 
    return function(){ 
     var xhr = this; 
     _core._fireAjaxEvents('pre', xhr._HREF); // preAjaxListener fires 

     var rsc = xhr.onreadystatechange || function(){}; // store the original onreadystatechange if it exists 
     xhr.onreadystatechange = function(){ // overwrite with custom function 
      try { 
       if (xhr.readyState == 4){ 
        _core._fireAjaxEvents('post', xhr._HREF); // postAjaxListneer should fire 
        this.onreadystatechange = rsc; 
       } 
      } catch (e){ } 
      return rsc.apply(this, arguments); // call original readystatechange function 
     }; 

     return orig.apply(this, arguments); // call original 'send' function 
    }; 
})(XMLHttpRequest.prototype.send); 

Я не хочу писать функции обертки для создания ajax-запросов. Я хочу, чтобы иметь возможность подключиться к любому запросу ajax, сделанному любой библиотекой (или с ванильным js) на странице.

До сих пор функционировала только функция preAjaxListener. Я не могу понять, почему, но кажется, что onreadystatechange никогда не называется. Любое руководство будет высоко оценено.

Работа демо: http://jsfiddle.net/_nderscore/QTQ5s/

+0

Почему вы прикасаетесь к родному прототипу? Создайте свой собственный объект-обертку. –

+1

Потому что я могу! :) Я знаю, что это грязно, но я не хочу писать функции-обертки для создания ajax-запросов. Я в ситуации, когда на странице есть скрипты, на которые у меня нет контроля, и я хочу иметь возможность подключиться к любому запросу ajax, сделанному любой библиотекой (или с vanilla js). – nderscore

+0

Итак, вы хотите захватить каждый запрос/ответ XHR на странице? –

ответ

5

Использование .onreadystatechange не работает, потому что я испытывал с JQuery и Ajax методы JQuery в манипулируют и удаляет onreadystatechange свойство.

Однако добавление прослушивателя событий для loadend работает просто отлично, но IE. Для IE я настраивал интервал вместо этого - не оптимальное решение, но оно работает для моих нужд. Я только предназначил этот сценарий для работы с IE8 + и современными браузерами.

XMLHttpRequest.prototype.send = (function(orig){ 
    return function(){ 
     _core._fireAjaxEvents('pre', this._HREF); 

     if (!/MSIE/.test(navigator.userAgent)){ 
      this.addEventListener("loadend", function(){ 
       _core._fireAjaxEvents('post', this._HREF); 
      }, false); 
     } else { 
      var xhr = this, 
      waiter = setInterval(function(){ 
       if(xhr.readyState && xhr.readyState == 4){ 
        _core._fireAjaxEvents('post', xhr._HREF); 
        clearInterval(waiter); 
       } 
      }, 50); 
     } 

     return orig.apply(this, arguments); 
    }; 
})(XMLHttpRequest.prototype.send); 
+0

Как мы можем использовать его? –

+0

Я запустил этот код, и после ajax на странице я вижу ошибку в консоли: 'Uncaught ReferenceError: _core не определен' –

+0

в Google Chrome 50 –

Смежные вопросы