我正在尝试在没有jQuery的情况下重现jQuery的函数ajaxComplete和ajaxStart,以便可以在没有库依赖项的任何环境中使用它们(这是一个特殊的用例)。这些功能允许在任何ajax请求之前和之后调用事件侦听器。在我的示例中,我将它们称为preAjaxListener和postAjaxListener。
我正在尝试通过连接到XMLHttpRequest对象并覆盖/装饰openand 来实现它send。是的,我知道这很脏。
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请求。我希望能够挂接到页面上任何库(或使用香草js)发出的任何ajax请求。
到目前为止,仅该preAjaxListener功能有效。我似乎无法弄清楚为什么,但似乎onreadystatechange从未有人称呼过。任何指导将不胜感激。
preAjaxListener
onreadystatechange
工作演示:http : //jsfiddle.net/_nderscore/QTQ5s/
使用.onreadystatechange不起作用,因为我正在使用jQuery进行测试,并且jQuery的ajax方法可以操纵并删除该onreadystatechange属性。
.onreadystatechange
但是,为loadendIE 添加事件侦听器的方法在所有地方都可以正常工作。对于IE,我改为设置时间间隔-不是最佳解决方案,但它可以满足我的需要。 我只打算将此脚本用于IE8 +和现代浏览器。
loadend
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);