2011-10-29 56 views
15

我正在使用HTML5上傳文件。我有一個按鈕單擊事件附加到函數uploadFile()。它工作正常。我也有一個單獨的按鈕來取消上傳。我知道我們需要調用xhr.abort();但是,如何訪問uploadCanceled函數中的xhr對象?我可以使xhr對象成爲全局的,但這不是正確的方法。有人可以在這裏指導我嗎?正在中止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"); 
    } 

乾杯

+0

你試圖訪問'xhr'一旦它被中止(內'uploadCanceled'),或者你需要達到它,所以你可以調用'abort'?下面的問題和你的評論似乎並不一致。 –

回答

16

addEventListener將設置的uploadCanceledxhr上下文(this):

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

例子:http://jsfiddle.net/wJt8A/


相反,如果您需要觸發xhr.abort通過「取消」點擊,您可以返回引用並添加任何偵聽器之後你需要:

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

例子:http://jsfiddle.net/rC63r/1/

+0

感謝您的回覆。這有很大幫助。 – lewis

+0

此代碼是否與IE7兼容? – moderns

+2

@moderns不完全。這個答案的焦點,xhr.status和xhr.abort(),在IE7中被支持。但是,只有IE9及更高版本支持['addEventListener()'](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener)。以前的版本使用['attachEvent()'](http://msdn.microsoft.com/zh-cn/library/ie/ms536343.aspx)。 「[正確使用addEventListener()/ attachEvent()?](http://stackoverflow.com/questions/2657182/correct-usage-of-addeventlistener-attachevent)」另外,問題中的FormData需要[IE 10和以後](http://caniuse.com/#feat=xhr2)。 –

2

您應該能夠引用 「this」 關鍵字在你的canceledUpload事件處理程序。這指的是XMLHttpRequest。把這個處理程序:

this.abort(); 
+0

感謝您的回覆。但是,如何在一個按鈕的幫助下調用uploadCanceled函數?我知道如果我重新加載頁面,它會被調用。我不認爲我可以將它關聯到onClick事件,然後使用this.abort()正確嗎? – lewis

+0

看看這個: http://jsfiddle.net/yE8r3/ 代碼不會在這裏運行,但顯示如何將東西封裝在閉包中。名爲s的對象在閉包和點擊處理程序中可見,但不在閉包之外。 – dnuttle

+0

什麼是cancelUpload事件處理程序? – stevemao

0

中止所有的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

如果是不必要的,無論如何檢查條件。設置.length看起來不太好。您可以逐個彈出它們或將該數組分配給[] – daghan