2016-10-31 6 views
0

Я работаю над этим в течение последних 6 часов, и я не могу понять это.Uncaught DOMException: Не удалось выполнить 'readAsDataURL' в 'FileReader': объект уже занят чтением Blobs. (...)

Я пытаюсь создать веб-сайт, на котором я выбираю папку изображений, и я показываю их в своем документе. Я получаю первое изображение для отображения, а затем получаю следующую ошибку в моей консоли.

Uncaught DOMException: Не удалось выполнить «readAsDataURL» на «FileReader»:. Объект уже занят Blobs чтения (...)

Я считаю, что проблема возникает из-за моей цикл, потому что FileReader является асинхронный. Но мне нужно пройти через весь массив для этого, так что я делаю неправильно?

Я загружаю файлы («проверит, чтобы убедиться, что я получу только изображения позже»), в массив, а затем я читаю каждый файл по одному. Прежде чем разбить мой код на функции, я сделал все в одной функции, и он работает! Я включил HTML + оригинальный и текущий JS-код. Спасибо, что нашли время, чтобы увидеть это.

HTML

<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="utf-8"> 
    <title>Tiled Image Viewer</title> 
    <script src="js/tiv.js"></script> 
    <link rel="stylesheet" href="style.css"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 

    </head> 
    <body> 

    <div id="main-wrap"> 
     <form name="uploadForm"> 

     <input id="images" type="file" webkitdirectory mozdirectory directory name="myFiles" 
        onchange="readAndShowFiles();" multiple/> 

     <span id="list"></span> 
     </form> 

    </div> 

    </body> 
</html> 

Javascript Оригинал:

function readAndShowFiles() { 
var files = document.getElementById("images").files; 
for (var i = 0; i < files.length; i++) { 
    var file = files[i]; 
    // Have to check that this is an image though 
    // using the file.name TODO 
    var reader = new FileReader(); 
    // Closure to capture the file information. 
    reader.onload = (function(file) { 
    return function(e) { 
     // Render thumbnail. 
     var span = document.createElement('span'); 
     span.innerHTML = ['<img src="', e.target.result, 
     '" title="', escape(file.name), '">'].join(''); 
     document.getElementById('list').insertBefore(span, null); 
    }; 
    })(file); 
    // Read in the image file as a data URL. 
    reader.readAsDataURL(file); 
} 
} 

Javascript Ток:

function readAndShowFiles() { 
    console.log("Checkpoint2"); //test 
    var tiv = new tivAPI(); 
    var array = tiv.getLoadedImages(); 
    tiv.showLoadedImages(array); 
} 

function tivAPI(){ 
    var imagesarray = new Array(); 


    return{ 
     loadImages: function(){ 
     console.log("Loading Files"); //test 
     var files = document.getElementById("images").files; 
     for (var i = 0; i < files.length; i++) { 
      var file = files[i]; 
      // Have to check that this is an image though 
      // using the file.name TODO 
     } 
     console.log(files.length); //test 
     return files; 
     }, 
     getLoadedImages: function(){ 
     imagesarray = this.loadImages(); 
     console.log("Returning Files"); //test 
     console.log(imagesarray.length); 
     return imagesarray; 
     }, 
     showLoadedImages: function(elem){ 
     console.log("Showing Files"); //test 
     var files = elem; 
     var reader = new FileReader(); 
     // Closure to capture the file information. 
     for (var i = 0; i < files.length; i++) { 
      var file = files[i]; 
      reader.onload = (function(file) { 
      return function(e) { 
       // Render thumbnail. 
       var span = document.createElement('span'); 
       span.innerHTML = ['<img src="', e.target.result, 
       '" title="', escape(file.name), '">'].join(''); 
       document.getElementById('list').insertBefore(span, null); 
      }; 

      })(file); 
     // Read in the image file as a data URL. 
     reader.readAsDataURL(file); 
     } 
     } 
    }; 
    } 

ответ

2

Причина, по которой ваш код использует тот же самый читатель, потому что вы используете одну и ту же переменную считывателя.
Какой доза Javascript в том, что все переменной получает перемещается к вершине, чтобы ваш проанализирован код выглядит примерно так

function readAndShowFiles() { 
    var files = document.getElementById("images").files; 
    var reader; 
    var file; 
    var i; 

    for (i = 0; i < files.length; i++) { 
    file = files[i]; 
    reader = new FileReader(); 
    reader.onload = (function(file) { 
     return function(e) { 
     var span = document.createElement('span'); 
     span.innerHTML = ['<img src="', e.target.result, 
      '" title="', escape(file.name), '">' 
     ].join(''); 
     document.getElementById('list').insertBefore(span, null); 
     }; 
    })(file); 
    reader.readAsDataURL(file); 
    } 
} 

вы могли бы избежать его довольно просто, просто перемещая всю логику внутри в annonymes функционировать

function readAndShowFiles() { 
    var files = document.getElementById("images").files; 

    for (var i = 0; i < files.length; i++) { 
    // Closure to capture the file information. 
    (function(file) { 
     var reader = new FileReader(); 
     reader.onload = function(e) { 
     // Render thumbnail. 
     var span = document.createElement('span'); 
     span.innerHTML = ['<img src="', e.target.result, 
      '" title="', escape(file.name), '">' 
     ].join(''); 
     document.getElementById('list').insertBefore(span, null); 
     }; 
     // Read in the image file as a data URL. 
     reader.readAsDataURL(file); 
    })(files[i]); 
    } 
} 

Теперь вы используете считыватель uniq для каждого файла.Следует также отметить, что это может быть проще, если вы только что сделали

array.from(files).forEach(function(file) { 
    // code 
}) 

Или просто использовали let переменную (таким образом, вы будете использовать другую FileReader каждый раз)

function readAndShowFiles() { 
    var files = document.getElementById("images").files; 

    for (var i = 0; i < files.length; i++) { 
    let file = files[i]; 
    let reader = new FileReader(); 
    reader.onload = function(e) { 
     // Render thumbnail. 
     var span = document.createElement('span'); 
     span.innerHTML = ['<img src="', e.target.result, 
     '" title="', escape(file.name), '">' 
     ].join(''); 
     document.getElementById('list').insertBefore(span, null); 
    }; 
    // Read in the image file as a data URL. 
    reader.readAsDataURL(file); 
    } 
} 

для цикла может быть записана проще с ES6 оставив вас с 2 меньше переменных

function readAndShowFiles() { 
    var files = document.getElementById("images").files; 

    for (let file of files) { 
    let reader = new FileReader(); 
    reader.onload = function(e) { 
     // Render thumbnail. 
     var span = document.createElement('span'); 
     span.innerHTML = ['<img src="', e.target.result, 
     '" title="', escape(file.name), '">' 
     ].join(''); 
     document.getElementById('list').insertBefore(span, null); 
    }; 
    // Read in the image file as a data URL. 
    reader.readAsDataURL(file); 
    } 
} 

, но если вы хотите это супер просто, почему бы не просто пропустить FileReader все togeth эр и избежать всех функций & обратных вызовов с использованием URL.createObjectURL createObjectURL сохранения процессора де/компиляции файла в/из base64

function showFiles() { 
    var files = document.getElementById("images").files; 

    for (let file of files) { 
    let img = new Image; 
    img.src = URL.createObjectURL(file); 
    img.title = file.name; 

    document.getElementById('list').appendChild(img); 
    } 
} 
0

Проблема возникла потому, что я пытался использовать один и тот же читатель для каждого изображения. Перемещение var reader = new FileReader(); в цикл (функция ShowLoadedImages), решение проблемы и отображение всех изображений, как предполагалось.

Смежные вопросы