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

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

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

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

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

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

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

;(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;
})();

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

 那如何才能正確地 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 添加了自定義事件。如何調(diào)用?

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 返回的內(nèi)容
});
 
xhr.open('GET', 'info.json');
xhr.send();

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

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

因?yàn)橐陨洗a使用了 CustomEvent 構(gòu)造函數(shù),在現(xiàn)代瀏覽器上可以正常使用,但是在 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;
})();

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

相關(guān)文章

  • JS克隆,屬性,數(shù)組,對象,函數(shù)實(shí)例分析

    JS克隆,屬性,數(shù)組,對象,函數(shù)實(shí)例分析

    這篇文章主要介紹了JS克隆,屬性,數(shù)組,對象,函數(shù),結(jié)合實(shí)例形式分析了javascript中面向?qū)ο蟪绦蛟O(shè)計(jì)相關(guān)的對象、屬性、函數(shù)及數(shù)組等相關(guān)技巧,需要的朋友可以參考下
    2016-11-11
  • js實(shí)現(xiàn)小窗口拖拽效果

    js實(shí)現(xiàn)小窗口拖拽效果

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

    JS數(shù)字精度丟失的原因及解決方案

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

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

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

    JavaScript統(tǒng)計(jì)字符出現(xiàn)次數(shù)

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

    JS實(shí)現(xiàn)快速比較兩個(gè)字符串中包含有相同數(shù)字的方法

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

    Js利用正則表達(dá)式去除字符串的中括號(hào)

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

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

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

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

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

    JavaScript實(shí)現(xiàn)圖片合成下載的示例

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

最新評(píng)論

会昌县| 论坛| 安图县| 晋州市| 舟曲县| 濮阳县| 金门县| 阳东县| 茂名市| 大足县| 鄂州市| 务川| 微山县| 集贤县| 孝感市| 突泉县| 西丰县| 密山市| 岫岩| 宁河县| 宜兰市| 宜兰县| 华容县| 桓仁| 漳浦县| 贺兰县| 聂拉木县| 巴中市| 连山| 渭源县| 榆林市| 五台县| 朝阳区| 庆城县| 长宁区| 临泽县| 堆龙德庆县| 房山区| 阜新市| 自贡市| 贞丰县|