2016-06-20 21 views
6

Questa funzione all'interno di un oggetto definisce la gestione degli eventi per un oggetto xmlhttprequest. Poiché alcuni browser non hanno accettato il metodo addEventListener, ho fatto un test e quindi non se, si definirà onstatechange:Come rilevare se il browser accetta eventi xmlhttprequest da addEventListener?

var reqEngatilhar = function(){ 
    este.concluido = false; 
    timeoutId = setTimeout(reqTimeout, este.timeout); 
    if(este.Request.hasOwnProperty("onload")){ 
     este.Request.addEventListener("error", reqErro, true); 
     este.Request.addEventListener("progress", reqMon, false); 
     este.Request.addEventListener("abort", reqAbort, false); 
     este.Request.addEventListener("load", reqFim, false); 
     console.log("$Http reqEngatilhar usando eventos..."); 
    } else { 
     este.Request.onreadystatechange = function (e) { reqSwitch(e); }; 
     console.log("$Http reqEngatilhar usando onreadystatechange..."); 
    } 
} 

Il "este" è "questo" al di fuori della funzione (var este = questo;)

Il "reqSwitch" punterà alla funzione corretta. Il problema è il test este.Request.hasOwnProperty ("onload") funziona solo in Safari. Come posso eseguire un test cross-browser per rilevare se il browser funzionerà con addEventListener?

+0

kill la parte hasOWnProperty, questi metodi sono ereditati: 'if (este.Request.onload! == undefined)' – dandavis

risposta

3

Basta verificare se l'oggetto ha addEventListener impostato su un valore di verità. Eseguendo il controllo in questo modo, non si dipende dalla gerarchia del prototipo utilizzata dal browser dietro le quinte. (. Come dandavis pointed out, può essere un problema)

if (este.Request.addEventListener) { 
    este.Request.addEventListener("error", reqErro, true); 
    // etc... 
} else { 
    este.Request.onreadystatechange = function (e) { reqSwitch(e); }; 
    console.log("$Http reqEngatilhar usando onreadystatechange..."); 
} 

Se siete preoccupati per gli strumenti che potrebbero Muck cose e impostare addEventListener ai valori funky, si potrebbe fare:

if (typeof este.Request.addEventListener === "function") { 
-1

Questo addEventListener polyfill potrebbe aiutare:

https://github.com/jonathantneal/EventListener

risparmiare la fatica di controllare la compatibilità del browser e lasciare che la polyfill gestire questo.

+0

Puoi indicare esattamente dove [nel polyfill] (https://github.com/jonathantneal/EventListener /blob/master/EventListener.js) il metodo 'addEventListener' viene aggiunto agli oggetti' XMLHttpRequest'? Ho guardato e guardato e mi sembra che questo polyfill sia solo per oggetti che fanno parte dell'albero DOM. – Louis

0

provarlo:

var util = { 
    getAttribute: function (dom, attr) { 
     if (dom.getAttribute !== undefined) { 
      return dom.getAttribute(attr); 
     } else if (dom[attr] !== undefined) { 
      return dom[attr]; 
     } else { 
      return null; 
     } 
    }, 
    addEvent: function (obj, evtName, func) { 
     //Primero revisar attributos si existe o no. 
     if (obj.addEventListener) { 
      obj.addEventListener(evtName, func, false); 

     } else if (obj.attachEvent) { 
      obj.attachEvent(evtName, func); 
     } else { 
      if (this.getAttribute("on" + evtName) !== undefined) { 
       obj["on" + evtName] = func; 
      } else { 
       obj[evtName] = func; 
      } 

     } 

    }, 
    removeEvent: function (obj, evtName, func) { 
     if (obj.removeEventListener) { 
      obj.removeEventListener(evtName, func, false); 
     } else if (obj.detachEvent) { 
      obj.detachEvent(evtName, func); 
     } else { 
      if (this.getAttribute("on" + evtName) !== undefined) { 
       obj["on" + evtName] = null; 
      } else { 
       obj[evtName] = null; 
      } 
     } 

    }, 
    getAjaxObject: function() { 
     var xhttp = null; 
     //XDomainRequest 
     if ("XMLHttpRequest" in window) { 
      xhttp = new XMLHttpRequest(); 
     } else { 
      // code for IE6, IE5 
      xhttp = new ActiveXObject("Microsoft.XMLHTTP"); 
     } 
     return xhttp; 
    } 

}; 

//START CODE HERE. 

var xhr = util.getAjaxObject(); 

var isUpload = (xhr && ('upload' in xhr) && ('onprogress' in xhr.upload)); 

if (isUpload) { 
    util.addEvent(xhr, "progress", xhrEvt.onProgress()); 
    util.addEvent(xhr, "loadstart", xhrEvt.onLoadStart); 
    util.addEvent(xhr, "abort", xhrEvt.onAbort); 
} 

util.addEvent(xhr, "readystatechange", xhrEvt.ajaxOnReadyState); 

var xhrEvt = { 
    onProgress: function (e) { 
     if (e.lengthComputable) { 
      //Loaded bytes. 
      var cLoaded = e.loaded; 
     } 
    }, 
    onLoadStart: function() { 
    }, 
    onAbort: function() { 
    }, 
    onReadyState: function() { 
     var state = xhr.readyState; 
     var httpStatus = xhr.status; 

     if (state === 4 && httpStatus === 200) { 
      //Completed success. 
     } 

    } 
}; 

//CONTINUE YOUR CODE HERE. 
-1

Provare il modo più vecchio per registrare eventi forse?

// Pass a function reference — do not add '()' after it, which would call the function! 
el.onclick = modifyText; 

// Using a function expression 
element.onclick = function() { 
    // ... function logic ... 
}; 

Verificare this post per saperne di più.

Problemi correlati