【问题标题】:Preview images before upload上传前预览图像
【发布时间】:2016-09-11 19:16:25
【问题描述】:

我有一个包含四张图片的页面供用户选择。我希望用户能够在上传之前预览网站上的每张图片。

下面的 JavaScript 代码仅适用于一张图片,但我希望它适用于通过 <input type="file"> 上传的多张图片。

最好的方法是什么?

function readURL(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();

        reader.onload = function (e) {
            $('#output').attr('src', e.target.result);
        }

        reader.readAsDataURL(input.files[0]);
    }
}

$("#file-input").change(function () {
    readURL(this);
});

【问题讨论】:

  • 也许使用jQuery File Upload插件之类的东西会更容易?
  • 不使用单个#output 图像?
  • 你的建议的一个例子会很棒@bergi

标签: javascript jquery html


【解决方案1】:

这里是 jQuery 版本。我认为这是更简单的事情。

$(function() {
    // Multiple images preview in browser
    var imagesPreview = function(input, placeToInsertImagePreview) {

        if (input.files) {
            var filesAmount = input.files.length;

            for (i = 0; i < filesAmount; i++) {
                var reader = new FileReader();

                reader.onload = function(event) {
                    $($.parseHTML('<img>')).attr('src', event.target.result).appendTo(placeToInsertImagePreview);
                }

                reader.readAsDataURL(input.files[i]);
            }
        }

    };

    $('#gallery-photo-add').on('change', function() {
        imagesPreview(this, 'div.gallery');
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="file" multiple id="gallery-photo-add">
<div class="gallery"></div>

【讨论】:

  • @Artem Solovev,我们可以在您的上述解决方案中设置最大图像数量吗?
  • 如何在此处添加删除?
  • @ArtemSolovev 如何在阅读器 onload 中获取i 值? alert(i) 将得到相同的结果
  • 我在函数顶部添加了$("div.gallery").html(""); 的一点点改动,这样每次选择文件时都会删除以前的缩略图
  • 如果用户选择同一张图片超过时间,它会再次显示同一张图片。
【解决方案2】:

multiple 属性添加到您的input 元素。

Javascript

function previewImages() {

  var preview = document.querySelector('#preview');
  
  if (this.files) {
    [].forEach.call(this.files, readAndPreview);
  }

  function readAndPreview(file) {

    // Make sure `file.name` matches our extensions criteria
    if (!/\.(jpe?g|png|gif)$/i.test(file.name)) {
      return alert(file.name + " is not an image");
    } // else...
    
    var reader = new FileReader();
    
    reader.addEventListener("load", function() {
      var image = new Image();
      image.height = 100;
      image.title  = file.name;
      image.src    = this.result;
      preview.appendChild(image);
    });
    
    reader.readAsDataURL(file);
    
  }

}

document.querySelector('#file-input').addEventListener("change", previewImages);
<input id="file-input" type="file" multiple>
<div id="preview"></div>

jQuery适配:

function previewImages() {

  var $preview = $('#preview').empty();
  if (this.files) $.each(this.files, readAndPreview);

  function readAndPreview(i, file) {
    
    if (!/\.(jpe?g|png|gif)$/i.test(file.name)){
      return alert(file.name +" is not an image");
    } // else...
    
    var reader = new FileReader();

    $(reader).on("load", function() {
      $preview.append($("<img/>", {src:this.result, height:100}));
    });

    reader.readAsDataURL(file);
    
  }

}

$('#file-input').on("change", previewImages);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="file-input" type="file" multiple>
<div id="preview"></div>

更多信息MDN readAsDataURL
StackOverflowPreview Image, get file size, image height and width before upload

【讨论】:

  • 嗨,谢谢你,它工作正常。我们如何为此添加删除选项?
【解决方案3】:

只需使用FileReader.readAsDataURL()

HTML:

<div id='photos-preview'></div>
<input type="file" id="fileupload" multiple (change)="handleFileInput($event.target.files)" />

JS:

 function handleFileInput(fileList: FileList) {
        const preview = document.getElementById('photos-preview');
        Array.from(fileList).forEach((file: File) => {
            const reader = new FileReader();
            reader.onload = () => {
              var image = new Image();
              image.src = String(reader.result);
              preview.appendChild(image);
            }
            reader.readAsDataURL(file);
        });
    }

DEMO

【讨论】:

  • 我们如何将它用于多个单独的输入标签?不是具有多个图像预览的单个输入
  • 嗨,Giorgi,对 FileList 使用 forEach,在任何文件上使用新的 FileReader 来读取AsDataURL。
【解决方案4】:

function previewMultiple(event){
        var saida = document.getElementById("adicionafoto");
        var quantos = saida.files.length;
        for(i = 0; i < quantos; i++){
            var urls = URL.createObjectURL(event.target.files[i]);
            document.getElementById("galeria").innerHTML += '<img src="'+urls+'">';
        }
    }
#galeria{
        display: flex;
    }
    #galeria img{
        width: 85px;
        height: 85px;
        border-radius: 10px;
        box-shadow: 0 0 8px rgba(0,0,0,0.2);
        opacity: 85%;
    }
<input type="file" multiple onchange="previewMultiple(event)" id="adicionafoto">
<div id="galeria">
    
</div>

【讨论】:

    【解决方案5】:

    $(function() {
        // Multiple images preview in browser
        var imagesPreview = function(input, placeToInsertImagePreview) {
    
            if (input.files) {
                var filesAmount = input.files.length;
    
                for (i = 0; i < filesAmount; i++) {
                    var reader = new FileReader();
    
                    reader.onload = function(event) {
                        $($.parseHTML('<img>')).attr('src', event.target.result).appendTo(placeToInsertImagePreview);
                    }
    
                    reader.readAsDataURL(input.files[i]);
                }
            }
    
        };
    
        $('#gallery-photo-add').on('change', function() {
            imagesPreview(this, 'div.gallery');
        });
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <input type="file" multiple id="gallery-photo-add">
    <div class="gallery"></div>

    function previewImages() {
    
      var preview = document.querySelector('#preview');
      
      if (this.files) {
        [].forEach.call(this.files, readAndPreview);
      }
    
      function readAndPreview(file) {
    
        // Make sure `file.name` matches our extensions criteria
        if (!/\.(jpe?g|png|gif)$/i.test(file.name)) {
          return alert(file.name + " is not an image");
        } // else...
        
        var reader = new FileReader();
        
        reader.addEventListener("load", function() {
          var image = new Image();
          image.height = 100;
          image.title  = file.name;
          image.src    = this.result;
          preview.appendChild(image);
        });
        
        reader.readAsDataURL(file);
        
      }
    
    }
    
    document.querySelector('#file-input').addEventListener("change", previewImages);
    <input id="file-input" type="file" multiple>
    <div id="preview"></div>

    【讨论】:

      【解决方案6】:

      function previewImages() {
      
        var preview = document.querySelector('#preview');
        
        if (this.files) {
          [].forEach.call(this.files, readAndPreview);
        }
      
        function readAndPreview(file) {
      
          // Make sure `file.name` matches our extensions criteria
          if (!/\.(jpe?g|png|gif)$/i.test(file.name)) {
            return alert(file.name + " is not an image");
          } // else...
          
          var reader = new FileReader();
          
          reader.addEventListener("load", function() {
            var image = new Image();
            image.height = 100;
            image.title  = file.name;
            image.src    = this.result;
            preview.appendChild(image);
          });
          
          reader.readAsDataURL(file);
          
        }
      
      }
      
      document.querySelector('#file-input').addEventListener("change", previewImages);
      <input id="file-input" type="file" multiple>
      <div id="preview"></div>

      【讨论】:

      • 我正在使用您的方法来检测类型,但它会发出警报并添加文件。我怎样才能避免这种情况?谢谢!
      【解决方案7】:
      <script type="text/javascript">
      
      var upcontrol = {
        queue : null, // upload queue
        now : 0, // current file being uploaded
        start : function (files) {
        // upcontrol.start() : start upload queue
      
          // WILL ONLY START IF NO EXISTING UPLOAD QUEUE
          if (upcontrol.queue==null) {
            // VISUAL - DISABLE UPLOAD UNTIL DONE
            upcontrol.queue = files;
            document.getElementById('uploader').classList.add('disabled');
            // PREVIEW UPLOAD IMAGES
             upcontrol.preview();*enter code here*
            //PROCESS UPLOAD ON CLICK 
      
          $('#add_files').on('click', function() {
             upcontrol.run();
          });
          }
        },
        preview : function() {
          //upcontrol.preview() : preview uploading file
              if (upcontrol.queue) {
                  var filesAmount = upcontrol.queue.length;
      
                  for (i = 0; i < filesAmount; i++) {
                      var reader = new FileReader();
      
                      reader.onload = function(event) {
                        var fimg = document.createElement('img') 
                          fimg.src =  event.target.result,
                            fimg.classList = "col-sm-6 col-md-6 col-lg-4 float-left center",
                            document.getElementById('gallery').appendChild(fimg);                
                      }
                      reader.readAsDataURL(upcontrol.queue[i]);
                  }
              }
          },
        run : function () {
        // upcontrol.run() : proceed upload file
      
          var xhr = new XMLHttpRequest(),
              data = new FormData();
          data.append('file-upload', upcontrol.queue[upcontrol.now]);
          xhr.open('POST', './lockeroom/func/simple-upload.php', true);
          xhr.onload = function (e) {
      
            // SHOW UPLOAD STATUS
            var fstat = document.createElement('div'),
      
                txt = upcontrol.queue[upcontrol.now].name + " - ";
            if (xhr.readyState === 4) {
              if (xhr.status === 200) {
                // SERVER RESPONSE
                txt += xhr.responseText;
              } else {
                // ERROR
                txt += xhr.statusText;
              }
            }
            fstat.innerHTML = txt;
            document.getElementById('upstat').appendChild(fstat);
      
            // UPLOAD NEXT FILE
            upcontrol.now++;
            if (upcontrol.now < upcontrol.queue.length) {
              upcontrol.run();
            }
            // ALL DONE
            else {
              upcontrol.now = 0;
              upcontrol.queue = null;
              document.getElementById('uploader').classList.remove('disabled');
            }
          };
          xhr.send(data);
        }
      };
      
      window.addEventListener("load", function () {
        // IF DRAG-DROP UPLOAD SUPPORTED
        if (window.File && window.FileReader && window.FileList && window.Blob) {
          /* [THE ELEMENTS] */
          var uploader = document.getElementById('uploader');
      
          /* [VISUAL - HIGHLIGHT DROP ZONE ON HOVER] */
          uploader.addEventListener("dragenter", function (e) {
            e.preventDefault();
            e.stopPropagation();
            uploader.classList.add('highlight');
          });
          uploader.addEventListener("dragleave", function (e) {
            e.preventDefault();
            e.stopPropagation();
            uploader.classList.remove('highlight');
          });
      
          /* [UPLOAD MECHANICS] */
          // STOP THE DEFAULT BROWSER ACTION FROM OPENING THE FILE
          uploader.addEventListener("dragover", function (e) {
            e.preventDefault();
            e.stopPropagation();
          });
      
          // ADD OUR OWN UPLOAD ACTION
          uploader.addEventListener("drop", function (e) {
            e.preventDefault();
            e.stopPropagation();
            uploader.classList.remove('highlight');
            upcontrol.start(e.dataTransfer.files);
          });
        }
        // FALLBACK - HIDE DROP ZONE IF DRAG-DROP UPLOAD NOT SUPPORTED
        else {
          document.getElementById('uploader').style.display = "none";
        }
      });
      </script>
      

      我使用了这样的东西,我得到了最好的结果并且易于理解。

      【讨论】:

      • 拖到这里


        将其用于 html 拖入式上传器
      【解决方案8】:
      function appendRows(){
          $i++;
          var html='';
          html+='<div id="remove'+$i+'"><input type="file" name="imagefile[]" accept="image/*" onchange="appendloadFile('+$i+')"><img id="outputshow'+$i+'" height="70px" width="90px"><i onclick="deleteRows('+$i+')" class="fas fa-trash-alt"></i></div>';
           $("#appendshow").append(html);
      }
      
      function appendloadFile(i){
          var appendoutput = document.getElementById('outputshow'+i+'');
          appendoutput.src = URL.createObjectURL(event.target.files[0]);
      }
      

      【讨论】:

        【解决方案9】:

        https://stackoverflow.com/a/59985954/8784402

        ES2017 方式

        // convert file to a base64 url
        const readURL = file => {
            return new Promise((res, rej) => {
                const reader = new FileReader();
                reader.onload = e => res(e.target.result);
                reader.onerror = e => rej(e);
                reader.readAsDataURL(file);
            });
        };
        
        // for demo
        const fileInput = document.createElement('input');
        fileInput.type = 'file';
        const img = document.createElement('img');
        img.attributeStyleMap.set('max-width', '320px');
        document.body.appendChild(fileInput);
        document.body.appendChild(img);
        
        const preview = async event => {
            const file = event.target.files[0];
            const url = await readURL(file);
            img.src = url;
        };
        
        fileInput.addEventListener('change', preview);

        【讨论】:

          【解决方案10】:

          $(function() {
              // Multiple images preview in browser
              var imagesPreview = function(input, placeToInsertImagePreview) {
          
                  if (input.files) {
                      var filesAmount = input.files.length;
          
                      for (i = 0; i < filesAmount; i++) {
                          var reader = new FileReader();
          
                          reader.onload = function(event) {
                              $($.parseHTML('<img>')).attr('src', event.target.result).appendTo(placeToInsertImagePreview);
                          }
          
                          reader.readAsDataURL(input.files[i]);
                      }
                  }
          
              };
          
              $('#gallery-photo-add').on('change', function() {
                  imagesPreview(this, 'div.gallery');
              });
          });
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          
          
          <input type="file" multiple id="gallery-photo-add">
          <div class="gallery">

          $(function() {
              // Multiple images preview in browser
              var imagesPreview = function(input, placeToInsertImagePreview) {
          
                  if (input.files) {
                      var filesAmount = input.files.length;
          
                      for (i = 0; i < filesAmount; i++) {
                          var reader = new FileReader();
          
                          reader.onload = function(event) {
                              $($.parseHTML('<img>')).attr('src', event.target.result).appendTo(placeToInsertImagePreview);
                          }
          
                          reader.readAsDataURL(input.files[i]);
                      }
                  }
          
              };
          
              $('#gallery-photo-add').on('change', function() {
                  imagesPreview(this, 'div.gallery');
              });
          });
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          
          
          <input type="file" multiple id="gallery-photo-add">
          <div class="gallery">

          【讨论】:

          • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
          猜你喜欢
          • 1970-01-01
          • 2011-05-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多