将参数传递给FileReader onload事件

Pass a parameter to FileReader onload event

本文关键字:onload 事件 FileReader 参数传递      更新时间:2023-09-26

我需要读取一些csv文件,由用户给出。使用拖放div将文件传递到页面/脚本,该div处理文件拖放,如下所示:

function handleFileDrop(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    var files = evt.dataTransfer.files; // FileList object.
    ...
}

我需要用csv库解析每个文件,该库将其转换为数组,但我还需要跟踪我当前正在解析的文件名。下面是我用来解析每个文件的代码:

for(var x = 0; x < files.length; x++){
    var currFile = files[x];
    var fileName = currFile.name;
    var reader = new FileReader();
    reader.onload = (function(theFile){
        return function(e){
            var csvArr = CSV.csvToArray( e.target.result, ";", true );
            console.log(csvArr); 
        };
    })(currFile);   
    reader.readAsText(currFile);
}

在此之前,一切都很顺利。我需要的是将文件名传递给reader.onload事件,例如:

reader.onload = (function(theFile){
    return function(e){
       ***** I need to have fileName value HERE *****
    };
})(currFile); 

是可能的吗?我该怎么做呢?提前感谢您的帮助,致以最诚挚的问候

尝试如下:

var reader = new FileReader();
reader.onload = (function(theFile){
    var fileName = theFile.name;
    return function(e){
        console.log(fileName);
        console.log(e.target.result);
    };
})(currFile);   
reader.readAsText(currFile);

在这里,每次将文件传递给外部方法时,都要创建一个新的fileName变量。然后创建一个可以访问该变量(由于闭包)并返回它的函数。

使用Blob API

使用新的File/Blob API可以更容易地完成。

你的第二个代码块——也解决了你的问题——可以重写为:

for (let file of files){
 (new Blob([file])).text().then(x=>console.log(file.name,x));
}

Blob API使用promise而不是像Filereader API那样使用Events,所以闭包的麻烦要少得多。此外,箭头函数(x=>)和迭代器for of,使代码更加简洁。

检查支持。

使用Fetch API

同样使用Fetch API响应对象可以更容易地完成。

for (let file of files){
 (new Response(file)).text().then(x=>console.log(file.name,x));
}

构造函数中缺少Array []说明

也检查支持。