简体   繁体   中英

Can't print file name before multiple image upload in jQuery

I am trying to get image previews and their names before uploading. But can't print the right name for every single image. I have tried

event.target.name which returns 'undefined' and file.name which returns name of 1st image for all the rest images. Any help would be appreciated.

<input type="file" name="file[]" id="image-upload" class="file-input" accept="image/*" multiple>
<div id="img-wrapper"></div>


<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>

<script type="text/javascript">
    $("#image-upload").change(function(){            
        var files = $(this)[0].files;

        for(var i = 0; i< files.length; i++) {
            var file = files[i];                
            var reader = new FileReader();                
            reader.onload = function(event){                    
                var img = event.target.result;

                console.log(event.target.name);   //prints 'undefined'
                console.log(file.name);           //prints 1st image's name for all images

                $('#img-wrapper').append("<img class='thumbnail' src='" + img + "'" +
                        "title='" + file.name + "'/>"); 

            };

            reader.readAsDataURL(file);
        }                               

    });
</script>

event.target.name is undefined because the target of the event is the FileReader object, not the file:

EXAMPLE

$("#image-upload").change(function() {
    $("#img-wrapper").empty();
    var files = $(this)[0].files;

    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        var reader = new FileReader();

        // Give the reader a name
        reader.name = 'Reader #' + i;

        reader.onload = function(event) {
            // Append the reader's name to the output
            $("#img-wrapper").append('<div>' + event.target.name + '<div>');
        };
    };

    reader.readAsDataURL(file);
});

Regarding your file name issue, the FileReader is asynchronous. From MDN :

The FileReader object lets web applications asynchronously read the contents of files (or raw data buffers) stored on the user's computer, using File or Blob objects to specify the file or data to read.

This means that your for-loop completes all its iterations before the onload callbacks are fired and file will always represent the last item that was seen in the loop. When the onload functions are fired, they all have the correct result (image) because you're using the event object, but they'll all use the same file .

EXAMPLE

$("#image-upload").change(function(){            
    var files = $(this)[0].files;

    for(var i = 0; i< files.length; i++) {
        var file = files[i];
        var reader = new FileReader();

        reader.name = 'Reader #'
        reader._i = i;

        $('#img-wrapper').append("<div>LOOP #" + i + "</div>");

        reader.onload = function(event) {
            var img = event.target.result;
            $('#img-wrapper').append("<div>READER #" + this._i +"</div>"); 

        };

        reader.readAsDataURL(file);
    }                               

});

You're going to have to restructure your code to be able to do what you want to do.

On second thought, you might not have to restructure much of anything. You can bind the onload function for each reader and pass in the file's name:

EXAMPLE

$("#image-upload").change(function() {
    var files = $(this)[0].files;

    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        var reader = new FileReader();

        // Note that parameters are reordered due to binding below
        reader.onload = (function(name, event) {
        var img = event.target.result;
        $('#img-wrapper').append(
            "<img class='thumbnail' src='" + img + "'" + "title='" + name + "'/>");
        }).bind(reader, file.name);

        reader.readAsDataURL(file);
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM