Si la demande Ajax est lancée par $.ajax de jQuery, par défaut, vous pouvez utiliser les gestionnaires mondiaux d'événements AJAX de JQuery pour écouter l'événement AJAX. Cependant, ce que j'ai rencontré, c'est une demande Ajax initiée avec JavaScript native, donc cette méthode ne fonctionne pas.
Ensuite, il existe d'autres méthodes, telles que Pub / Sub, mais je ne peux pas modifier le code JS qui initie la demande, il n'y a donc aucun problème à ajouter de publication au code. De même, .bind et .trigger de jQuery ne peuvent pas être utilisés.
Enfin, j'ai décidé d'utiliser le override XMLHttpRequest lors de l'utilisation d'événements personnalisés.
En cherchant sur Stackoverflow, j'ai trouvé qu'un méchant donnait une solution peu fiable. Eh bien, je le posterai pour que vous voyiez:
; (function () {var open = window.xmlhttprequest.prototype.open, send = window.xmlhttprequest.prototype.send, onreadystatechange; function openReplacement (méthode, url, async, user, mot de passe) {// quelque code return open.Apply (this, arments);} function envoy if (this.onreadystatechange) arguments);} window.xmlhttprequest.prototype.open = OpenReplacement; Cette solution ne peut pas écouter tous XHR Events , et l'événement readystatechange n'est écouté qu'après avoir appelé la méthode send , il ne peut donc pas écouter les événements lorsque readyState = 1 . Dans le même temps, si vous définissez une fonction de rappel pour onreadystatechange après avoir utilisé la méthode send , le code override sera à nouveau override et l'effet attendu ne sera pas produit.
Alors, comment puis-je remplacer correctement XHR? Postez le code et jetons un coup d'œil:
(function () {function ajaxEventTrigger (event) {var ajaxEvent = new Customevent (event, {Detail: this}); window.dispatchEvent (ajaxEvent);} var oldxhr = window.xmlhttprequest; function newxhr () {var realXhr = newxhr ();); realXhr.addeventListener («abort», function () {ajaxEventTright.call (this, 'ajaxabort');}, false); {ajaxEventTright.call (this, 'ajaxload');}, false); 'ajaxtimeout');}, false); }, false); De cette façon, un événement personnalisé est ajouté à XHR . Comment appeler?
var xhr = new xmlHttpRequest (); window.addeventListener ('ajaxReadyStateChange', fonction (e) {console.log (e.detail); // xmlHttpRequest objet}); window.addeventListener ('ajaxabort', fonction (e) {console.log (e.detail.ResponSeText); // contenu renvoyé par xhr}); xhr.open ('get', 'info.json'); xhr.send (); Il convient de noter que e renvoyé par l'objet normal readystatechange et d'autres handler est l'objet XMLHttpRequest , mais e renvoyé par la méthode personnalisée ajaxReadyStateChange et d'autres gestionnaires d'événements est l'objet CustomEvent , et e.detail est le véritable objet XMLHttpRequest . e.responseText qui obtient le contenu renvoyé par la demande AJAX doit également être modifié sur e.detail.responseText .
Dans le même temps, addEventListener doit être montée sur window 对象, pas sur XHR .
Parce que le code ci-dessus utilise le constructeur CustomEvent , il peut être utilisé normalement dans les navigateurs modernes, mais sous IE, même IE 11 ne le prend pas en charge, donc Polyfill doit être ajouté, et cela devient ceci:
(function () {if (typeof window.customevent === "function") return false; function Customevent (événement, params) {params = params || {bubbles: false, annule: false, détail: undefined}; var evt = document.createevent ('customevent'); evt.initCustomEvent (event, params.bubbles, paramds.cancier, params.DeTomEvent); return evt;} customevent.prototype = window.event.prototype; Windows.xmlhttprequest; ajaxEventTright.call (this, 'ajaxerror');}, false); 'ajaxloadstart');}, false); realXhr.addeventListener ('timeout', function () {ajaxEventTright.call (this, 'ajaXtimeout');}, false); realXhr.addeventListener ('readyStateChange', function () {ajaxEventTright.call (this, 'ajaxreadystatechange');}, false);À l'heure actuelle, vous pouvez l'utiliser avec bonheur sur IE 9+, Chrome 15+, Firefox 11+, Edge, Safari 6.1+ et Opera 12.1+. Ce qui précède est tout le contenu de cet article. J'espère que vous l'aimez.