简体   繁体   中英

Preload images from more then one file input

I find an methode to preload an image before uploading, but i have more then one file input. And i want for each input file to preload the image. In generell not a big problem but the amount how many file inputs are used on the website is not stable. An user can addan upload image block so he can add 2 or 3 and i want for each he ads the possibility to preload the image. But my experience dont reach this level what it needs. So my question is it possible to realilze it? My code for preload the image for one specific file input is this:

    function readURL(input) {
          if (input.files && input.files[0]) {
                    var reader = new FileReader();
                    reader.onload = function (e) {
                              $('#blah')
                                        .attr('src', e.target.result)
                                        .height(50);
                    };
                    reader.readAsDataURL(input.files[0]);
          }
}

If an user adds one image block this is how it looks like:

<div id="divImage-1" class="form-group form-file-upload">
<label id="labelImage-1" for="labelImage2-1">New Picture</label>
<div></div>
<label id="labelImage2-1" for="inputImage-1" class="form-file-upload1">Upload Image</label>
<input id="inputImage-1" type="file" onchange="readURL(this);">
<img id="blah" height="50" alt="Image preview">
</div>

If the user create an second one all IDs ae count to 2 (divImage-2).

Lets assume you this in your HTML

<button class="btn btn-primary" id="addBtn">Add Image Block</button>

<div class="container"></div>

Then, as first step you need to create two global variables:

  1. let imageBlockCout = 0 for counting number of image blocks.
  2. let addedPicSet = nnew Set() a set of pic names which are being used by other blocks.

Then for every click on add button we will add a new block of image with code lets say:

    $(
      $.parseHTML(
        `<div class="row">
                <input type="file" multiple id="photos-${imageBlockCount}">
                <div id="gallery-${imageBlockCount}" class="row"></div>
             </div>`
      )
    ).appendTo(".container");

Now, for every file input added you need to attach an on-change listener:

   let currentBlockCount = imageBlockCount;
    $("#photos-" + imageBlockCount).on("change", function () {
      let input = this;

      if (!input.files) {
        return;
      }

      //for every image that has been read by FileReader we show it
      //in its own card inside its button gallery
      let onFileLoaded = function (event) {
        $(
          $.parseHTML(
            `<div class="col-sm-3">
                <div class="card">
                  <img 
                    class="card-img-top" 
                    src="${event.target.result}">
                </div>
              </div`
          )
        ).appendTo("#gallery-" + currentBlockCount);
      };

      //input.files is an array like object, so we convert it to array
      Array.from(input.files)
        .filter(
          //first we filter images which are already in use
          (file) => !addedPicSet.has(file.name)
        )
        .forEach((file) => {
          let reader = new FileReader();
          //we attach an onLoad listener for each reader
          reader.onload = onFileLoaded;

          //then we tell the reader object which file to read
          reader.readAsDataURL(file);

          //add the image name in the set of used image names
          addedPicSet.add(file.name);
        });
    });

I have also made a pen for your help: https://codepen.io/abdullah-shabaz/pen/qBdvZMQ

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