使用“预览”上传多个文件(图像)会使浏览器崩溃

时间:2018-08-16 23:44:06

标签: javascript jquery html css

由于某些奇怪的原因,当我尝试上传多个甚至一个图像时,在将所有图片加载到.img_container中之后,整个浏览器冻结并崩溃。我不知道我的jquery代码是否有错误,但这没有任何意义,因为我的代码之前运行得很好,而且我从未碰过它。现在,它无处不在使我的浏览器崩溃。我正在使用Firefox,并且尝试使用Chrome,但是我猜我的jQuery代码或CSS无法与Chrome一起使用,原因是图片未加载到预览div中。这是第二次发布此帖子,因为我考虑过将图片上传到下面的代码段中,但仍然再次导致浏览器崩溃。

$(function() {
        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);
                        $(document).find('img img').addClass('imageClass');
                    }

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

        };

        $('#upload-image').on('change', function() {
            imagesPreview(this, 'img.image');
        });
    });
input {
  width: 100%;
  font-size: 16px;
  border: 2px solid #FFF;
  border-radius: 3px;
  padding: 5px 5px;
  margin: 3px 3px;
  box-sizing: border-box;
}
.field-wrap {
  position: relative;
  margin-bottom: 10px;
  padding-top: 8px;
  width: 40%;
}
.form {
  background: #CCC;
  max-width: 100%;
  border-radius: 4px;
  margin: 20px;
}
.img_container {
    justify-content: center;
    display: flex;
    border: 2px solid #CCC;
    min-height: 220px;
    max-height: 220px;
    overflow: scroll;
    user-drag: none;
    user-select: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<form id='imageForm' action='' method='POST' enctype='multipart/form-data'>
    <div class="field-wrap">
        <input id='upload-image' type='file' name='files[]' multiple>
    </div>
    <div class="field-wrap">
        <input type='submit' value='Upload'>
    </div>
    <div class='img_container'><img class='image'></div>
</form>

2 个答案:

答案 0 :(得分:1)

对我来说,很奇怪的是,您尝试将图像附加到自封标签中,例如<img class='image'>,图像不能包含任何其他元素。

这就是我所做的:

  • 我用FileReader删除了异步URL.createObjectURL(file),它更快,更聪明,并且不需要在base64之间来回解码/编码
  • 然后在加载图像后撤消objectUrl以释放所有引用,以便浏览器可以对其进行垃圾回收
  • 您也不必再检查if(input.files),所有现代浏览器现在都拥有该功能。
  • 并且我将文件输入更改为仅接受image/*,以便更轻松地从对话框中选择图像

jQuery(function($) {
  function imagesPreview(input, placeToInsertImagePreview) {
    var len = input.files.length;

    for (i = 0; i < len; i++) {
      var img = new Image();
      img.src = URL.createObjectURL(input.files[i])
      img.className = 'imageClass';
      img.onload = function(){
        URL.revokeObjectURL(img.src)
      }
      $(img).appendTo(placeToInsertImagePreview);
    }
  };

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

<form id='imageForm' action='' method='POST' enctype='multipart/form-data'>
  <div class="field-wrap">
    <input id='upload-image' accept="image/*" type='file' name='files[]' multiple>
  </div>
  <div class="field-wrap">
    <input type='submit' value='Upload'>
  </div>
  <div class='img_container'><div class='image'></div>
</form>

答案 1 :(得分:0)

以下是一个可以帮助您的示例:

function toBase64(file) {
  return new Promise(function(resolve, reject) {
    var reader = new FileReader();
    reader.onload = function() {
      resolve(reader.result);
    };
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}

function preview(files) {
  $('.img_container').html('')
  for (var i in files) {
    var promise = toBase64(files[i]);
    promise.then(function(result) {
      $('.img_container').append(`<img class="image" src="${result}">`)
    });
  }
}
   
.img_container {
  border: 2px solid #CCC;
  min-height: 158px;
}
.image{width:100px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input onchange="preview(this.files)" type='file' name='files[]' multiple>
<div class='img_container'></div>