最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

分享JavaScript監(jiān)聽全部Ajax請求事件的方法

 更新時間:2016年08月28日 16:22:07   投稿:daisy  
最近在做一個小項目,引入了第三方js文件,這個文件會調用XMLHttpRequest向服務器發(fā)送 Ajax請求,但是我有需要監(jiān)聽其Ajax請求的某些事件,以便額外地執(zhí)行其他腳本。于是稍微看了看監(jiān)聽 Ajax請求的事件方法,在這里分享給大家。有需要的朋友們可以參考借鑒。

若Ajax請求是由jQuery的$.ajax發(fā)起的,默認情況下可以使用 jQuery的Global Ajax Event Handlers監(jiān)聽到Ajax事件,然而我遇到的卻是用原生JavaScript發(fā)起的Ajax請求,所以這種方法行不通。

然后呢,還有其他方法,比如說 Pub/Sub,但是這個發(fā)起請求的 js 代碼我是無法改動的,也就不存在向代碼里添加 publish 的問題。同理,jQuery 的 .bind.trigger 也無法使用。

最后,決定使用直接 override XMLHttpRequest,同時配合使用自定義事件。 

在 StackOverflow 上搜索,發(fā)現有個歪果仁給出了一個不靠譜的解決方法,嗯,貼出來給大家看看:

;(function () {
 var open = window.XMLHttpRequest.prototype.open,
  send = window.XMLHttpRequest.prototype.send,
  onReadyStateChange;
 
 function openReplacement(method, url, async, user, password) {
  // some code
 
  return open.apply(this, arguments);
 }
 
 function sendReplacement(data) {
  // some code
 
  if(this.onreadystatechange) this._onreadystatechange = this.onreadystatechange;
  this.onreadystatechange = onReadyStateChangeReplacement;
 
  return send.apply(this, arguments);
 }
 
 function onReadyStateChangeReplacement() {
  // some code
 
  if (this._onreadystatechange) return this._onreadystatechange.apply(this, arguments);
 }
 
 window.XMLHttpRequest.prototype.open = openReplacement;
 window.XMLHttpRequest.prototype.send = sendReplacement;
})();

這個解決方案,無法監(jiān)聽全部的 XHR Events ,而且 readystatechange 事件是在調用 send 方法后才監(jiān)聽,也就無法監(jiān)聽到 readyState = 1 時的事件。同時,如果在使用 send 方法后再對 onreadystatechange 設置回調函數,會將 override 的代碼又一次 override,也就無法產生預想的效果。

 那如何才能正確地 override XHR 呢?貼上代碼,一起來看看:

;(function() {
 function ajaxEventTrigger(event) {
  var ajaxEvent = new CustomEvent(event, { detail: this });
  window.dispatchEvent(ajaxEvent);
 }
  
 var oldXHR = window.XMLHttpRequest;
 
 function newXHR() {
  var realXHR = new oldXHR();
 
  realXHR.addEventListener('abort', function () { ajaxEventTrigger.call(this, 'ajaxAbort'); }, false);
 
  realXHR.addEventListener('error', function () { ajaxEventTrigger.call(this, 'ajaxError'); }, false);
 
  realXHR.addEventListener('load', function () { ajaxEventTrigger.call(this, 'ajaxLoad'); }, false);
 
  realXHR.addEventListener('loadstart', function () { ajaxEventTrigger.call(this, 'ajaxLoadStart'); }, false);
 
  realXHR.addEventListener('progress', function () { ajaxEventTrigger.call(this, 'ajaxProgress'); }, false);
 
  realXHR.addEventListener('timeout', function () { ajaxEventTrigger.call(this, 'ajaxTimeout'); }, false);
 
  realXHR.addEventListener('loadend', function () { ajaxEventTrigger.call(this, 'ajaxLoadEnd'); }, false);
 
  realXHR.addEventListener('readystatechange', function() { ajaxEventTrigger.call(this, 'ajaxReadyStateChange'); }, false);
 
  return realXHR;
 }
 
 window.XMLHttpRequest = newXHR;
})();

這樣,就為 XHR 添加了自定義事件。如何調用?

var xhr = new XMLHttpRequest();
 
window.addEventListener('ajaxReadyStateChange', function (e) {
 console.log(e.detail); // XMLHttpRequest Object
});
window.addEventListener('ajaxAbort', function (e) {
 console.log(e.detail.responseText); // XHR 返回的內容
});
 
xhr.open('GET', 'info.json');
xhr.send();

需要注意的是,正常的 readystatechange 等事件 handler 返回的 eXMLHttpRequest 對象,但是自定義方法 ajaxReadyStateChange 等事件 handler 返回的 eCustomEvent 對象,而 e.detail 才是真正的 XMLHttpRequest 對象。而獲得 Ajax 請求返回內容的 e.responseText 也需要修改為 e.detail.responseText。

同時,addEventListener 方法必須掛載在 window 對象上,而不能是 XHR 實例上。 

因為以上代碼使用了 CustomEvent 構造函數,在現代瀏覽器上可以正常使用,但是在 IE 下,甚至連 IE 11 都不支持,所以需要加上 Polyfill,變成這樣:

;(function () {
 if ( typeof window.CustomEvent === "function" ) return false;
 
 function CustomEvent ( event, params ) {
  params = params || { bubbles: false, cancelable: false, detail: undefined };
  var evt = document.createEvent( 'CustomEvent' );
  evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
  return evt;
 }
 
 CustomEvent.prototype = window.Event.prototype;
 
 window.CustomEvent = CustomEvent;
})();
;(function () {
 function ajaxEventTrigger(event) {
  var ajaxEvent = new CustomEvent(event, { detail: this });
  window.dispatchEvent(ajaxEvent);
 }
  
 var oldXHR = window.XMLHttpRequest;
 
 function newXHR() {
  var realXHR = new oldXHR();
 
  realXHR.addEventListener('abort', function () { ajaxEventTrigger.call(this, 'ajaxAbort'); }, false);
 
  realXHR.addEventListener('error', function () { ajaxEventTrigger.call(this, 'ajaxError'); }, false);
 
  realXHR.addEventListener('load', function () { ajaxEventTrigger.call(this, 'ajaxLoad'); }, false);
 
  realXHR.addEventListener('loadstart', function () { ajaxEventTrigger.call(this, 'ajaxLoadStart'); }, false);
 
  realXHR.addEventListener('progress', function () { ajaxEventTrigger.call(this, 'ajaxProgress'); }, false);
 
  realXHR.addEventListener('timeout', function () { ajaxEventTrigger.call(this, 'ajaxTimeout'); }, false);
 
  realXHR.addEventListener('loadend', function () { ajaxEventTrigger.call(this, 'ajaxLoadEnd'); }, false);
 
  realXHR.addEventListener('readystatechange', function() { ajaxEventTrigger.call(this, 'ajaxReadyStateChange'); }, false);
 
  return realXHR;
 }
 
 window.XMLHttpRequest = newXHR;
})();

此時,就可以在 IE 9+、Chrome 15+、FireFox 11+、Edge、Safari 6.1+、Opera 12.1+ 上愉快地使用了,以上就是本文的全部內容,希望大家能夠喜歡。

相關文章

  • JS克隆,屬性,數組,對象,函數實例分析

    JS克隆,屬性,數組,對象,函數實例分析

    這篇文章主要介紹了JS克隆,屬性,數組,對象,函數,結合實例形式分析了javascript中面向對象程序設計相關的對象、屬性、函數及數組等相關技巧,需要的朋友可以參考下
    2016-11-11
  • js實現小窗口拖拽效果

    js實現小窗口拖拽效果

    這篇文章主要為大家詳細介紹了js實現小窗口拖拽效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • JS數字精度丟失的原因及解決方案

    JS數字精度丟失的原因及解決方案

    JS的數字類型一旦數字超過限值,JS將會丟失精度,導致前后端的值出現不一致,這篇文章主要給大家介紹了關于JS數字精度丟失的原因分析及解決方法,需要的朋友可以參考下
    2022-04-04
  • JavaScript的介紹和簡單語法(示例代碼)

    JavaScript的介紹和簡單語法(示例代碼)

    JavaScript是一種廣泛使用的腳本語言,為網頁添加交互性和動態(tài)功能提供了強大的支持,在本文中,我們將深入了解JavaScript的基本概念和用法,包括它在HTML中的書寫位置、注釋和結束符的使用,以及一種常用的函數——alert語句,感興趣的朋友一起看看吧
    2023-09-09
  • JavaScript統(tǒng)計字符出現次數

    JavaScript統(tǒng)計字符出現次數

    這篇文章主要為大家詳細介紹了JavaScript字符統(tǒng)計出現次數,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • JS實現快速比較兩個字符串中包含有相同數字的方法

    JS實現快速比較兩個字符串中包含有相同數字的方法

    這篇文章主要介紹了JS實現快速比較兩個字符串中包含有相同數字的方法,涉及javascript字符串的遍歷、排序、比較等相關操作技巧,需要的朋友可以參考下
    2017-09-09
  • Js利用正則表達式去除字符串的中括號

    Js利用正則表達式去除字符串的中括號

    這篇文章主要給大家介紹了關于Js利用正則表達式去除字符串的中括號的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • Js如何判斷客戶端是PC還是手持設備簡單分析

    Js如何判斷客戶端是PC還是手持設備簡單分析

    在工作過程中,許多朋友會經常用到js判斷客戶端是PC還是手持設備,今天將提供以下方法,需要的朋友可以參考下
    2012-11-11
  • 微信小程序登錄數據解密及狀態(tài)維持實例詳解

    微信小程序登錄數據解密及狀態(tài)維持實例詳解

    這篇文章主要介紹了微信小程序登錄數據解密及狀態(tài)維持,結合實例形式分析了微信小程序解密敏感信息及獲取session保持登陸狀態(tài)的相關操作技巧,需要的朋友可以參考下
    2019-05-05
  • JavaScript實現圖片合成下載的示例

    JavaScript實現圖片合成下載的示例

    這篇文章主要介紹了JavaScript實現圖片合成下載的示例,幫助大家更好的理解和學習JavaScript,感興趣的朋友可以了解下
    2020-11-11

最新評論

竹北市| 内黄县| 卢氏县| 乌拉特前旗| 绩溪县| 陇川县| 淮滨县| 大城县| 南昌县| 大英县| 昭通市| 南郑县| 皮山县| 镇安县| 芜湖县| 登封市| 沅江市| 周宁县| 双城市| 玉田县| 房山区| 灵台县| 门源| 同德县| 仁寿县| 黔江区| 遂川县| 灵川县| 潍坊市| 乐亭县| 肇庆市| 丰城市| 江孜县| 余姚市| 玉屏| 临朐县| 和田县| 肇东市| 乃东县| 阿拉善左旗| 澜沧|