2014-12-02 18 views
18

parametresine sahip FileReader onload Yükleyicinin hem sonucun sonucunu hem de bir yükleme fonksiyonundaki bazı parametreleri almayı başaramıyorum. Ben onload işlevinde, filereader.result kullanmakSonuç ve parametre

files_input.addEventListener("change", openFiles, false); 

:

function openFiles(evt){ 
    var files = evt.target.files; 
    for (var i = 0; i < files.length; i++) { 
     var file=files[i]; 
     reader = new FileReader(); 
     reader.onload = function(){ 
      var data = $.csv.toArrays(this.result,{separator:'\t'}); 
     }; 
     reader.readAsText(file); 
    } 
    } 

Etkinlik ekle: kontrolden

HTML:

<input type="file" id="files_input" multiple/> 

JavaScript işlevi Bu benim kodudur. Bu işlev için dosya gibi bir parametre kullanırsam, artık sonuca erişemiyorum. Örneğin, onload fonksiyonunda file.name kullanmak istiyorum. Bu sorun nasıl çözülür?

+0

bunu bir dosya ile çalışır? Farklı okuyucular oluşturmayı deneyin, "var reader = new FileReader();" –

+0

Basit bir kural kullanın: Tüm yerel değişkenleri kapatmanın başlangıcında bildirin. Onları, 'in' ve diğer benzer ifadeler içinde bildirmeyin, çünkü bu ifadeler kapanma oluşturmaz ve sonuç olarak bildirilen değişkenler ifadenin yerel değildir. Bu, ek kapatmalar oluşturmanız gerektiğinde karar vermenize yardımcı olacaktır. – hon2a

cevap

28

Yükleme işlevinizi başka bir işlevde sarmayı deneyin.

  • JavaScript closure inside loops – simple practical example
  • : Bir kapatma burada neden gerekli olduğu hakkında bir tartışma için
    function openFiles(evt){ 
        var files = evt.target.files; 
    
        for (var i = 0, len = files.length; i < len; i++) { 
         var file = files[i]; 
    
         var reader = new FileReader(); 
    
         reader.onload = (function(f) { 
          return function(e) { 
           // Here you can use `e.target.result` or `this.result` 
           // and `f.name`. 
          }; 
         })(file); 
    
         reader.readAsText(file); 
        } 
    } 
    

    bu ilgili soruları bakın: Burada kapatma değişkene f aracılığıyla sırayla işlenen her dosya erişim sağlar Javascript infamous Loop issue?
+2

Eğer tarayıcı 'FileReader' varsa, forEach ve bind'i desteklediğini düşünüyorum :) Daha iyi bir öneri olan geri yükleme çağrısı için – Pinal

+0

@Pinal dosyasına dosya eklemek için daha iyi bir bindim. Cevabımı bunlara eklemek için güncellemem, çünkü cevabımı OP tarafından sağlanan kodun yakınına koymak ve sadece gerekli olanı değiştirmek (kapama tanıtmak) değiştirmek istedim, ancak bu özelliklerin farkında olmak güzel. – Chris

+0

Benzer bir boşta, üretim kodunda, FileReader kodunu döngüden çağrılan kendi adlandırılmış işlevine taşımak cazip olurdu. Kapanışlar beklendiği gibi davranır ve kodun bozulmasına yardımcı olur. Verilen örnek, teknik çözümü göstermek için daha uygun olduğunu söyledi. – Hargobind

5

'Yükü kaldırma' işleyicisinde kapatmayı kullanmalısınız. Örnek: Değişken dosya kapsamında olduğu için http://jsfiddle.net/2bjt7Lon/

reader.onload = (function (file) { // here we save variable 'file' in closure 
    return function (e) { // return handler function for 'onload' event 
     var data = this.result; // do some thing with data 
    } 
})(file); 
-1

, bunu işlev geçmeden dosya değişken kullanabilir.

function openFiles(evt){ 
 
    var files = evt.target.files; 
 
    for (var i = 0; i < files.length; i++) { 
 
      var file=files[i];  
 
      reader = new FileReader(); 
 
      reader.onload = function(){ 
 
       alert(file.name); 
 
       alert(this.result); 
 
      }; 
 
     reader.readAsText(file); 
 
    } 
 
    } 
 

 
files_input.addEventListener("change", openFiles, false);
<input type="file" id="files_input" multiple/>

+0

'file' döngüde değişecek ... Örneğiniz yanlış çalışıyor – Pinal

+0

Bu işe yaramaz, neden http://stackoverflow.com/q/1451009/623518 bakın. – Chris

+0

Teşekkürler evet anladım :) Ama her dosya adını ve içeriğini görüntüleyerek test ettiğimde bu çalışıyor gibi görünüyor. Kod Snippet'ini yukarıdaki çalıştırın. Sanırım göreceğim bir şey eksik. – Banu

3

Olay işleme eşzamansız ve böylece hepsi kapalı lokal değişkenler (yani. Kapanması) en son değeri al. Etkinliğe belirli yerel değişkeni bağlamak için, ya da bu çalışma örnek bakabilirsiniz yukarıda kullanıcılar tarafından önerilen kodunu takip etmek gerekir: -

http://jsfiddle.net/sahilbatla/hjk3u2ee/

function openFiles(evt){ 
    var files = evt.target.files; 
    for (var i = 0; i < files.length; i++) { 
    var file=files[i]; 
    reader = new FileReader(); 
    reader.onload = (function(file){ 
     return function() { 
     console.log(file) 
     } 
    })(file); 
    reader.readAsText(file); 
    } 
} 

#Using jQuery document ready 
$(function() { 
    files_input.addEventListener("change", openFiles, false); 
}); 
+0

Bu tam olarak doğru değil. Reader.onload'a bir işlev atamalısınız. Çağırdığınız IIFE hiçbir şey döndürmez, bu yüzden okuyucu yük olayını tetiklediğinde hiçbir kod çalışmaz. – Chris

+0

Bir işlev döndürmenin neden önemli olduğunu anlamıyorum, kod parçası yalnızca onload olayında çalışacak ve dosyaya bağlandığında – sahilbathla

+0

Şu anda işleviniz (işlev (dosya) {console.log (dosya) }) (dosya); '' for' döngüsünüzün her yinelemesi için bir kez çalıştırılır. Hiçbir şey döndürmez, bu nedenle döngüdeki her bir interaksiyon için 'reader.onload = undefined'. Bu nedenle, 'console.log' dosyanız doğru dosya adını yazdırırken,' okuyucu' '' load' olayını tetiklediğinde hiçbir şey çalışmaz. – Chris

İlgili konular