2011-10-29 20 views
15

Estoy usando HTML5 para cargar archivos. Tengo un evento de clic de botón conectado a la función uploadFile(). Funciona bien. También tengo un botón por separado para cancelar la carga. Sé que debemos llamar a xhr.abort(); Pero, ¿cómo accedo al objeto xhr en la función uploadCanceled? Puedo hacer que el objeto xhr sea global, pero esa no es la forma correcta. ¿Puede alguien guiarme aquí?Cancelando el xmlhttprequest

function uploadFile(){ 
    var filesToBeUploaded = document.getElementById("fileControl"); 
    var file = filesToBeUploaded.files[0]; 
    var xhr= new XMLHttpRequest(); 
    xhr.upload.addEventListener("progress", uploadProgress, false); 
    xhr.addEventListener("load", uploadComplete, false); 
    xhr.addEventListener("error", uploadFailed, false); 
    xhr.addEventListener("abort", uploadCanceled, false); 


    xhr.open("POST", "upload.php", true); 

    var fd = new FormData(); 
    fd.append("fileToUpload", file); 
    xhr.send(fd); 
} 


    function uploadCanceled(evt) { 
     alert("Upload has been cancelled"); 
    } 

Saludos

+0

¿Está intentando acceder a la 'xhr' vez que ha sido abortado (dentro de' uploadCanceled') o usted ¿Necesitas alcanzarlo para que puedas llamar 'abortar '? Su pregunta y sus comentarios a continuación no parecen alinearse entre sí. –

Respuesta

16

addEventListener establecerá el contexto (this) de uploadCanceled a xhr:

function uploadCanceled(evt) { 
    console.log("Cancelled: " + this.status); 
} 

Ejemplo: http://jsfiddle.net/wJt8A/


Si, en cambio, es necesario disparar xhr.abort a través de un clic en "Cancelar", puede devolver una referencia y agregar cualquier oyente que necesita después de que:

function uploadFile() { 
    /* snip */ 
    xhr.send(fd); 

    return xhr; 
} 

document.getElementById('submit').addEventListener('click', function() { 
    var xhr = uploadFile(), 
     submit = this, 
     cancel = document.getElementById('cancel'); 

    function detach() { 
     // remove listeners after they become irrelevant 
     submit.removeEventListener('click', canceling, false); 
     cancel.removeEventListener('click', canceling, false); 
    } 

    function canceling() { 
     detach(); 
     xhr.abort(); 
    } 

    // detach handlers if XHR finishes first 
    xhr.addEventListener('load', detach, false); 

    // cancel if "Submit" is clicked again before XHR finishes 
    submit.addEventListener('click', canceling, false); 

    // and, of course, cancel if "Cancel" is clicked 
    cancel.addEventListener('click', canceling, false); 
}, false); 

Ejemplo: http://jsfiddle.net/rC63r/1/

+0

Gracias por la respuesta. Eso ayudó mucho. – lewis

+0

¿Este código es compatible con IE7? – moderns

+2

@moderns No del todo. El foco de esta respuesta, 'xhr.status' y' xhr.abort() ', se admite en IE7. Pero, ['addEventListener()'] (https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener) solo es compatible con IE9 y versiones posteriores. Las versiones anteriores en su lugar usaban ['attachEvent()'] (http://msdn.microsoft.com/en-us/library/ie/ms536343.aspx). "[Uso correcto de addEventListener()/attachEvent()?] (Http://stackoverflow.com/questions/2657182/correct-usage-of-addeventlistener-attachevent)" Además, 'FormData' de la pregunta requiere [IE 10 y más tarde] (http://caniuse.com/#feat=xhr2). –

2

Usted debe ser capaz de hacer referencia a la palabra "this" en el controlador de eventos canceledUpload. Eso se refiere a XMLHttpRequest. Poner esto en el controlador:

this.abort(); 
+0

gracias por la respuesta. ¿Pero cómo llamo a la función uploadCanceled con la ayuda de un botón? Sé que se llamará si vuelvo a cargar la página. No creo que pueda asociarlo a un evento onClick y luego usar this.abort() ¿no? – lewis

+0

Mira esto: http://jsfiddle.net/yE8r3/ El código no se ejecuta aquí, pero muestra cómo ajustar las cosas en un cierre. El objeto llamado s es visible dentro del cierre y el manejador de clics, pero no fuera del cierre. – dnuttle

+0

¿Qué es un controlador de eventos 'cancelledload'? – stevemao

0

Abortar todos XMLHttpRequest:

var array_xhr = new Array(); 
function uploadFile(){ 
    ... 
    var xhr = new XMLHttpRequest(); 
    array_xhr.push(xhr); 
    ... 
} 

function abort_all_xhr(){ 
    if (array_xhr.length>0) { 
     for(var i=0; i<array_xhr.length; i++){ 
      array_xhr[i].abort(); 
     } 
     array_xhr.length = 0; 
    }; 
} 

abort_all_xhr(); 
+1

si es innecesario, para cheques que condicionan de todos modos. El ajuste .length no parecía bueno. Puede mostrarlos uno por uno o asignar la matriz a [] – daghan