javascript – Bind Filereader (). Onprogress event with multiple progress elements

Question:

The project has a loader for images with "thumbnails" and there are several progress elements to display the loading process for each image separately. But the code above displays progress only on the last created progress element. Please tell me how to make sure that the loading process of each image is displayed in the corresponding progress element?

function processFiles (files) {var numFiles = files.length;

for (var i = 0, numFiles = files.length; i < numFiles; i++) {
    var f = files[i];

  // Обрабатываем только графические файлы !
  if (!f.type.match('image.*')) {
    continue;
  }

 //Проверяем существует ли элемент img если нет то запишем следующую картинку в него
 for (var e = 0; e < image_amount_restriction; e++) 
 {
     if (document.getElementById("img"+e)==null) 
     {
         element_id=e;
         break;
     }
}

var last = image_amount_restriction - element_id;
console.log(last);
if ( last < 2) {return false;}



//создем обьекты UI
 var parent = document.getElementById("photos");
 var div = document.createElement("div");
 div.id = ("block"+element_id);
 div.className  = "editbox";

 parent.appendChild(div);

 var parentE2 = document.getElementById("block"+element_id);
 var edit_panel = document.createElement("span");
 edit_panel.className = "edit_panel";
 edit_panel.id = ("edit_panel"+element_id);

 var hiddenfield = document.createElement("input");
 hiddenfield.type = "hidden";
 hiddenfield.name ="output[]";
 hiddenfield.id =("out"+element_id);

 parentE2.appendChild(hiddenfield);

 var img = document.createElement("img");
 img.classList.add("obj");
 img.id = ("img"+element_id);

 parentE2.appendChild(edit_panel);
 parentE2.appendChild(img);

 //прогрессбар
 var progressbar = document.createElement("progress");
 progressbar.id = ("my-progress"+element_id);
 progressbar.className = "progressbar";
 parentE2.appendChild(progressbar);

 var parentE3 = document.getElementById("edit_panel"+element_id);
 var trash_can = document.createElement("a");
 trash_can.className = "foto_n1";
 trash_can.id = element_id;
 trash_can.href = "#";
 trash_can.onclick = remove;

 parentE3.appendChild(trash_can);



 var reader = new FileReader();

//Недоделанный прогрессбар! 
reader.onprogress = function(event) 
{

if (event.lengthComputable) 
    {
        console.log(progressbar.id);
        progressbar.max = event.total;
        progressbar.value = event.loaded;   
    }
}

reader.onloadend = function(event) 
{
    var contents = event.target.result,
    error = event.target.error;
    if (error != null) 
    {
        console.error("File could not be read! Code " + error.code);
    } 
    else 
    {
        progressbar.max = 1;
        progressbar.value = 1;
     }
    }



 // Пишем картинки после загрузки в соответсвующие контейнеры
 reader.onload = (function(aImg,hiddenfield,progressbar) 
 {
     return function(e) 
     { 
        aImg.src = e.target.result;
        hiddenfield.value=e.target.result;
        //когда загрузились, скрываем прогресс бар
        progressbar.className += " hidden";
    }; 
})
(img,hiddenfield,progressbar);

  reader.readAsDataURL(f);
}   

Answer:

Most likely, this is due to the fact that the closure was not used when binding the handler. Because the required code is not visible, then I will try to advise "by eye":

        for (i=0; i<arFiles.length; i++){       
            var reader = new FileReader();
            reader.addEventListener('progress', (function(i){
                                                return function(event){ progressHook(event, i) }
                                            })(i) );
        ...
            reader.readAsDataURL(arFiles[i]);
        }

In the progressHook(event, i) function progressHook(event, i) first parameter is an event, and the second is the ordinal number of the file whose progress you want to track.

Scroll to Top