FileReader - 准备新文件,即使是同一个文件

时间:2016-11-08 16:14:57

标签: javascript filereader addeventlistener

我有几个加载文件html元素,例如:

<input type="file" id="loadFiles0" class="filesclass" name="file" />
<input type="file" id="loadFiles1" class="filesclass" name="file" />

我已经为他们添加了一个事件监听器来捕捉变化:

// Elsewhere
function myFunction(event){
    // Stuff
}

var el;
el = document.getElementById("loadFiles0");
el.addEventListener('change', myFunction, false);

许多人都知道,为了让负载第二次运行,即使它是同一个文件名,你必须设置html元素的值&#39;到&#34;&#34;。这就是问题。我需要知道哪个加载文件元素执行了调用。它是loadFiles0&#39;或者&#39; loadFiles1&#39;等

myFunction看起来像这样 - 只是重要的一点:

function myFunction(evt){

    ...


    // We need to remove it so this is not handled again when we set value = ""
    this.removeEventListener('change', myFunction, false);

    ...

    var reader = new FileReader();
    reader.onload = function (e) {
        ...

        // HERE IS THE PROBLEM
        // I need a reference to the dom element that this is working on - call it 'ptr'
        // I cannot use 'this' in this function, because that refers to 'reader'
        // I need it so I can set its value to "", so even if the person reloads the same file, it will trigger a change
        // But I cannot be certain if it was 'loadFiles0' or 'loadFiles1' etc
        ptr.value = "";
        ptr.addEventListener('change', myFunction, false);
    };
}

所以问题是,如何在读者的onload功能中获得ptr?

1 个答案:

答案 0 :(得分:1)

  

我需要知道哪个加载文件元素执行了调用。它是loadFiles0&#39;或者&#39; loadFiles1&#39;等

this的事件回调中myFunction,您可以记住变量(也许是ptr),或者如果您想使用ES2015(带有必要时进行转换)你可以使用箭头功能。

使用ptr

function myFunction(evt){

    // ...


    this.removeEventListener('change', myFunction, false);

    var ptr = this; // *******

    // ...

    var reader = new FileReader();
    reader.onload = function (e) {
        ptr.value = "";
        ptr.addEventListener('change', myFunction, false);
    };
}

或使用ES2015 +箭头功能:

function myFunction(evt){

    // ...


    this.removeEventListener('change', myFunction, false);

    // ...

    var reader = new FileReader();
    reader.onload = e => {                                   // ***
        this.value = "";                                     // ***
        this.addEventListener('change', myFunction, false);  // ***
    };
}

使用setTimeout模拟reader.onload回调的示例:

&#13;
&#13;
function myFunction(e) {
  var ptr = this;
  // This emulates the reader.onload callback:
  setTimeout(function() {
    console.log("reader.onload for " + ptr.id);
  }, 10);
}
Array.prototype.forEach.call(
  document.querySelectorAll("input[type=file]"),
  function(input) {
    input.addEventListener("change", myFunction, false);
  }
);
&#13;
<input type="file" id="loadFiles0">
<input type="file" id="loadFiles1">
<input type="file" id="loadFiles2">
&#13;
&#13;
&#13;

箭头功能示例:

&#13;
&#13;
// ES2015 or higher (you can transpile if necessary)
function myFunction(e) {
  // This emulates the reader.onload callback:
  setTimeout(() => {
    console.log("reader.onload for " + this.id);
  }, 10);
}
Array.prototype.forEach.call(
  document.querySelectorAll("input[type=file]"),
  function(input) {
    input.addEventListener("change", myFunction, false);
  }
);
&#13;
<input type="file" id="loadFiles0">
<input type="file" id="loadFiles1">
<input type="file" id="loadFiles2">
&#13;
&#13;
&#13;