2014-01-30 47 views
0

我在查看新的HTML5文件API以顯示要上傳的圖像的預覽。我搜索了一些代碼,幾乎每個例子都有相同的結構,幾乎相同的代碼。我不介意複製,特別是當它有效時,但我需要了解它。所以我試圖理解代碼,但我堅持一個區域,需要有人解釋一小部分:需要在HTML5文件API的圖像預覽中使用澄清

該代碼是指一個HTML表單輸入字段,當選擇該文件時,在img標籤中顯示預覽圖像。沒有什麼花哨。簡單。這是消除所有的噪聲後:

$('input[type=file]').change(function(e) { 
    var elem = $(this); 
    var file = e.target.files[0]; 
    var reader = new FileReader(); 

    //Part I could not understand starts here 
    reader.onload = (function(theFile) { 
    return function(e) { 
     var image_file = e.target.result    
     $('#img_id').attr('src',image_file); 
    }; 
    })(file); 
    reader.readAsDataURL(file); 
    //Upto here 
}); 

我認爲reader.onload需要分配一個普通的事件處理程序,所以我換成上面標有整款:

reader.readAsDataURL(file); 
    reader.onload = function(e) { 
     var image_file = e.target.result;   
     //#img_id is the id of an img tag 
     $('#img_id').attr('src',image_file) 
    }; 

它按我預期的那樣工作。

問題:上述簡化代碼丟失的原始代碼是什麼?我明白這是一個函數表達式,返回一個函數,然後調用它...但是爲了什麼?在教程中複製了太多的原始代碼,並且沒有包含它,但沒有很好的解釋。請解釋。謝謝

回答

1

當然。
函數包裝的函數在這裏提供了記住它正在查看的文件的具體目的。

這可能是少用你確切的代碼庫的問題,但如果你有一個多上傳控件,你想顯示預覽一行:

var my_files = [].slice.call(file_input.files), 

    file, reader, 

    i = 0, l = my_files.length; 


for (; i < l; i += 1) { 
    file = my_files[i]; 
    reader = new FileReader(); 

    // always put the handler first (upside down), because this is async 
    // if written normally and the operation finishes first (ie:cached response) 
    // then handler never gets called 
    reader.onload = function (e) { 
     var blob_url = e.target.result, 
      img = new Image(); 

     img.src = blob_url; 
     document.body.appendChild(img); 
    }; 
    reader.readAsDataUrl(file); 
} 

這應該一切工作的罰款。 ...除了... 它乾淨可讀。

,目前正在解決這個問題很簡單:

我們正在處理異步處理,這意味着file值不一定相同回調火災,因爲它是以前的時候。 ..

有很多方法可以解決這個問題。
幾乎所有這些都不會產生隨機ID /序列號/基於時間的散列來檢查返回,依靠關閉。

爲什麼我要創建一個完整的管理系統,什麼時候可以將它包裝在一個函數中並完成?

var save_file_reference_and_return_new_handler = function (given_file) { 
    return function (e) { 
     var blob_url = e.target.result, 
      file_name = given_file.name; 

     //... 
    }; 
}; 

所以,如果你有這樣的功能(環以上)的頂部,你可以說:

reader = new FileReader(); 
reader.onload = save_file_reference_and_return_new_handler(file); 
reader.readAsDataUrl(file); 

現在它會工作得很好。

當然,JS人們並不總是覺得有必要寫命名的功能,只是一個項目存儲在封閉以後記得......

reader.onload = (function (current_file) { 
    return function (e) { 
     var blob_url = e.target.result, 
      file_name = current_file.name; 
    }; 
}(file)); 
+0

完美。實際上,網上的大部分代碼都涉及多個上傳和預覽。這是我見過的最清晰和最有說服力的解釋。你應該寫一本書...很好地解釋了幾個主題。希望我會多次接受你的回答。謝謝! – Sam