Как передать дополнительные параметры объекту события javascript? - PullRequest
3 голосов
/ 03 сентября 2010

Я использую HTML 5 FileReader для асинхронного чтения более одного файла.

Я бы хотел следить за загрузкой отдельных файлов, так как можно добавить сразу несколько файлов.

Теперь я создал div с фоном 0% для каждого изображения, но мне не ясно, как передать идентификатор или ссылку этого подразделения в событии onprogress, чтобы я мог отслеживать прогресс и динамически обновлять содержимое div.

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

var up_file = document.getElementById('multiple_file'); 
        if(up_file.files)
        {   
            for(var x=0; x <up_file.files.length; x++)
            {
                //console.log(up_file.files.length);
                var file = up_file.files[x];

                var loadingDiv = document.createElement("div");
                var container = document.getElementById('loading_container');   

                loadingDiv.className = "loading";
                loadingDiv.id ="loading_" + x;
                loadingDiv.innerHTML = '0%';
                container.appendChild(loadingDiv);


                var reader = new FileReader();  

                reader.onprogress = function (evt) {
                  if (evt.lengthComputable) {
                  console.dir(evt);
                    // evt.loaded and evt.total are ProgressEvent properties
                    var loaded = (evt.loaded / evt.total);
                    if (loaded < 1) {
                        console.log(loaded);
                    }
                  }
                }

                var img = document.createElement("img");
                img.className = "hide";
                reader.onload = (function(aimg) {
                    return function(e) {
                        LIB.addEvent(aimg, "load", function(){
                            var scale = 1;
                            scale = aimg.width / 200;
                            aimg.width = aimg.width  / scale;
                            aimg.className = "show";
                        }, false);
                        aimg.src = e.target.result; 
                        var li = document.createElement("li");
                        li.appendChild(aimg);
                        document.getElementById('img_packet').appendChild(li);
                    };
                })(img);
                reader.readAsDataURL(file);
            }
        }

1 Ответ

4 голосов
/ 03 сентября 2010

loadingDiv все еще виден внутри функции onprogress, поскольку замыкание сформировано. Проблема в том, что он находится в цикле, поэтому к тому времени, когда вызывается onprogress, loadingDiv, вероятно, будет присвоено новое значение.

Чтобы обойти это, вы можете использовать дополнительное закрытие, чтобы взять копию текущего значения loadingDiv:

reader.onprogress= function(myloadingdiv) {
    return function(evt) {
        if (evt.lengthComputable)
            myloadingdiv.innerHTML= evt.loaded/evt.total*100+'%';
    };
}(loadingDiv);

В пятом издании ECMAScript метод bind() сделает это для вас более чисто:

reader.onprogress= function(myloadingdiv, evt) {
    if (evt.lengthComputable)
        myloadingdiv.innerHTML= evt.loaded/evt.total*100+'%';
}.bind(loadingDiv);

Для браузеров, которые еще не поддерживают bind(), вы можете внести исправления в реализацию следующим образом:

if (!('bind' in Function.prototype)) {
    Function.prototype.bind= function(owner) {
        var that= this;
        if (arguments.length<=1) {
            return function() {
                return that.apply(owner, arguments);
            };
        } else {
            var args= Array.prototype.slice.call(arguments, 1);
            return function() {
                return that.apply(owner, arguments.length===0? args : args.concat(Array.prototype.slice.call(arguments)));
            };
        }
    };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...