問(wèn)題描述
我正在嘗試重現(xiàn) jQuery 的函數(shù) ajaxComplete 和 ajaxStart 沒(méi)有 jQuery,因此它們可以在沒(méi)有庫(kù)依賴的任何環(huán)境中使用(這是一個(gè)特殊的用例).這些函數(shù)允許在任何 ajax 請(qǐng)求之前和之后調(diào)用事件偵聽(tīng)器.在我的示例中,我稱它們?yōu)?preAjaxListener 和 postAjaxListener.
I'm trying to reproduce jQuery's functions ajaxComplete and ajaxStart without jQuery so that they could be used in any environment with no library dependencies (it's a special use case). These functions allow for an event listener to be called before and after any ajax request. In my example, I call them preAjaxListener and postAjaxListener.
我試圖通過(guò)連接到 XMLHttpRequest 對(duì)象并覆蓋/裝飾 open
和 send
來(lái)完成它.是的,我知道這很臟.
I'm trying to accomplish it by hooking into the XMLHttpRequest object and overwriting/decorating open
and send
. Yes, I know this is dirty.
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);
我不想編寫(xiě)包裝函數(shù)來(lái)發(fā)出 ajax 請(qǐng)求.我希望能夠掛鉤頁(yè)面上任何庫(kù)(或使用 vanilla js)發(fā)出的任何 ajax 請(qǐng)求.
I do not want to write wrapper functions to make ajax requests. I want to be able to hook into any ajax request made by any library (or with vanilla js) on the page.
到目前為止,只有 preAjaxListener
函數(shù)有效.我似乎無(wú)法弄清楚為什么,但似乎 onreadystatechange
從未被調(diào)用過(guò).任何指導(dǎo)將不勝感激.
So far, only the preAjaxListener
function works. I can't seem to figure out why, but it seems that onreadystatechange
is never being called. Any guidance would be greatly appreciated.
工作演示:http://jsfiddle.net/_nderscore/QTQ5s/
推薦答案
使用 .onreadystatechange
不起作用,因?yàn)槲艺谑褂?jQuery 進(jìn)行測(cè)試,并且 jQuery 的 ajax 方法操作并刪除了 onreadystatechange代碼>屬性.
Using .onreadystatechange
wasn't working because I was testing with jQuery and jQuery's ajax methods manipulate and removes the onreadystatechange
property.
但是,為 loadend
添加事件偵聽(tīng)器在除 IE 之外的任何地方都可以正常工作.對(duì)于 IE,我設(shè)置了一個(gè)間隔 - 不是最佳解決方案,但它可以滿足我的需要.我只打算讓這個(gè)腳本在 IE8+ 和現(xiàn)代瀏覽器上運(yùn)行.
However, adding an event listener for loadend
works just fine everywhere but IE. For IE, I set up an interval instead - not the optimal solution, but it works for my needs. I only intended this script to work on IE8+ and modern browsers.
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);
這篇關(guān)于重新創(chuàng)建 jQuery 的 ajaxStart 和 ajaxComplete 功能的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!