【问题标题】:jQuery FileReader MultiplejQuery FileReader 多个
【发布时间】:2018-04-12 01:47:54
【问题描述】:

我是脚本新手。我有一个要添加多个的输入文件。上传图片后,每张图片的名称将与叉号一起显示,以便用户可以删除或添加更多图片。我还有一个预览容器来显示上传图像预览,每当用户添加或删除任何图像时我希望更新它。

演示:

https://codepen.io/alikhan999/pen/oqOLqP

脚本

$(document).ready(function() {

var bgRendered;
$('#PageBGimageBtn').on('change', function(){

 if( $(this).val().length ){
 var BGimageBtn = $(this);
 var inputFiles = this.files;
 //var inputFile = inputFiles[0];
 $(inputFiles).each(function(index) {
    var inputFile = inputFiles[index];
    
    if( inputFile.size < 2000000) {
        
        if ( inputFile.type === 'image/jpeg' || inputFile.type === 'image/png' || inputFile.type === 'image/gif'  ) {               
            var BGcontainer = '<div id="BG-'+index+'" class="imgName"><span>'+inputFile.name+'</span><i class="fas fa-times"></i></div>';
            $(BGimageBtn).closest('.uploadBtn').append(BGcontainer);
            
            var reader = new FileReader();
            reader.readAsDataURL(inputFile);
            reader.onloadend = function(){
                bgRendered = URL.createObjectURL(inputFile);
                var slideRendered = '<div id="slideBG-'+index+'" style="background-image:url('+bgRendered+')"></div>';
                $('#background').append(slideRendered);
            };
            

            
        } else {
            alert('Only Image files are allowed');  
        }
        
    } else {
        alert('Image should be less than 2MB');
    }
    
});
}

});
});

问题:

  1. 既然是多次上传,那么如何提醒用户哪个文件的文件扩展名无效或超出文件大小限制。
  2. 我不知道如何在单击名称时删除特定图像,以及如何在用户添加或删除任何图像时相应地更新预览部分。

【问题讨论】:

    标签: jquery filereader


    【解决方案1】:

    FileList 接口仍然不是真正的编程友好,因为我们没有真正的内置方法来修改它(附加/拼接)。

    所以最好的办法是尽快离开这个界面。为此,您可以使用一个数组,您将在其中放置文件。

    注意:您没有说明您将如何处理这些文件。但是如果你需要上传,那么既然我们去掉了FileList,我们将不得不使用AJAX来发送这些文件,以及FormData API,但这是为了以后。

    关于如何让您的用户知道其中一个文件无效,请在您的预览界面中进行。

    既然我们在这里,您还可以在文件周围创建一个包装对象,而不是将文件直接存储在我们的数组中,该对象还将包含您需要的预览元素。

    另外请注意,您在这里不需要 FileReader。要在网页中加载 Blob 或 File 对象,就好像它来自服务器一样,请改用 URL.createObjectURL 方法。

    var file_list = []; // our array that will hold all our FileWrappers
    $('#inp').on('change', function(evt) {
      var wrapper;
      for(var i = 0; i < inp.files.length; i++) {
        wrapper = new FileWrapper(inp.files[i]);
        $('#preview').append(wrapper.el);
        file_list.push(wrapper);
      }
    });
    
    $('#upload').on('click', function(evt) {
      var files = file_list.filter(function isValid(wrapper) {
        return wrapper.isValid;
      }).map(function getFile(wrapper) {
        return wrapper.file;
      });
      var fd = new FormData();
      files.forEach(function(file) {
        fd.append('files[]', file);
      });
        
      var xhr = new XMLHttpRequest();
      xhr.open('post', 'your_server_address');
    //  xhr.send(fd);
    // won't work in SO snippets so we log their values instead
      for([key, value] of fd.entries()) {
        console.log(key, value);
      }
    });
      
        
    
    function FileWrapper(file) {
      this.isValid = isValid(file);
      this.file = file;
      var remove = this.remove.bind(this);
      this.el = initElements();
    
      function isValid(file) {
        return file &&
          file instanceof Blob &&
          file.type.indexOf('image/') === 0 &&
          file.size &&
          file.size < 200000;
      }
      function initElements() {
        var el = $('<div>', {class:'file-wrapper'}).append(
          $('<button>', {text: 'x'})
            .on('click', remove),
          $('<p>', {class:'file-name', text: file.name || 'no name'}),
          $('<img>', {src: URL.createObjectURL(file), alt: 'invalid file'})
            .on('error', toggleInvalid)
        );
       if(this.invalid) {
        toggleInvalid();
       }
       return el;
       function toggleInvalid() {
         el.addClass('invalid');
       }
     }      
    }
    FileWrapper.prototype = Object.create({
      remove: function() {
        var index = file_list.indexOf(this);
        if(index > -1) {
          file_list.splice(index, 1);
        }
        this.el.remove();
      }
    });
    .input-wrapper {
      border: 1px solid;
      display: inline-block;
      padding: 0 2px;
      border-radius: 4px;
      cursor: pointer;
      position: relative;
    }
    .input-wrapper > input {
      opacity: 0;
      width: 100%;
      height: 100%;
      position: absolute;
    }
    #preview {
      vertical-align : top;
    }
    .file-wrapper{
      display: inline-block;
      padding: 4px;
      border: 1px solid;
      width: 150px;
      height: 150px;
      text-align: center;
      vertical-align: top;
      margin: 2px;
    }
    .file-wrapper.invalid{
      color: red;
    }
    .file-wrapper p{
      margin: 0;
      max-width: calc(100% - 20px);
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .file-wrapper button{
      float: right;
    }
    .file-wrapper img{
      max-height: 100px;
      max-width: 150px;
      display: block;
      margin: 10px auto 0px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="input-wrapper"><input type="file" id="inp" multiple><span>add new files</span></div>
    <button id="upload">upload to server</button>
    <div id="preview"></div>

    【讨论】:

    • 朋友 我正在尝试创建一个界面,用户可以在其中选择他想要的幻灯片图像。实际预览将是一个正在运行的幻灯片,将根据添加或删除的图像进行更新。最后,所有图像都将使用 jsZip 实用程序添加到一个 zip 文件中
    • 同样的模式适用。将 FileList 中的文件移动到数组中并从数组中工作。
    • 朋友 我修改了我的演示以实际展示我想要做什么。 codepen.io/alikhan999/pen/oqOLqP 因为我的代码没有数组来存储文件,所以我可以在添加新图像时更新我的​​幻灯片,但在删除图像时不能更新
    • 我还使用您的代码创建了一个新演示,但我不知道如何使用您的代码创建带有图像的幻灯片,以及如何在添加或删除图像时管理幻灯片。演示:codepen.io/alikhan999/pen/pLBMrW
    • 我确实需要一个文件阅读器在幻灯片图像 src 或预览图像 src 中的某个时刻天气,以便稍后 jsZip 可以将该图像数据呈现为新图像。
    猜你喜欢
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    • 2020-01-25
    相关资源
    最近更新 更多