如何将多个文件图像加载为数据URL,然后分别更改它们

时间:2019-03-23 10:36:27

标签: javascript jquery html5 image

在HTML页面上,使用img元素设置了两个图像。我想通过浏览pc目录来更改每个图像。没有数据库。更改图像后,如果重新加载页面,将显示旧图像。 即每个图像下方都有输入选项。如果要更改第二张图片,请单击第二张图片下方的“选择文件”选项,这将打开选择单个图片的窗口。

我有一段代码。

<input type='file' accept='image/*' onchange='openFile(event)'>
 <img id='output' width=20>

<input type='file' accept='image/*' onchange='openFile(event)'>
 <img id='output' width=20>

<input type='file' accept='image/*' onchange='openFile(event)'>
 <img id='output' width=20>

<script>
  var openFile = function(event) {
  var input = event.target;

  var reader = new FileReader();
  reader.onload = function(){
  var dataURL = reader.result;
  var output = document.getElementById('output');
  output.src = dataURL;
};
reader.readAsDataURL(input.files[0]);
};
</script>

使用此代码,我只能上传一个img元素的图像。但是,如果我想将其用于两个img元素,那么如果我将id“输出”更改为类“输出”,则无法使用。我需要了解它的原因以及可能产生多个图像的解决方案。

https://www.javascripture.com/FileReader

1 个答案:

答案 0 :(得分:1)

以下代码显示:

  • 如何使用一个文件输入来加载多个数据url,并为每个文件创建一个图像框(图像+文件输入+删除按钮)。
  • 如何分别更改每个图像框的加载图像。
  • 如何完全删除图像框。

摘要说明:

  • 点击蓝色的大+号,将一个或多个图像添加到列表中。
  • 点击图片进行更改单独
  • 单击图像右上角的红叉将其删除。

所有文件输入都在后台(更改hidden类以显示它们),它们只是被隐藏了,因为看起来更好。

var container = document.getElementById('img_container');
var placeholder = document.getElementById('placeholder');

// utility function doing both createElement and setAttributes
function create(elementName, attributes) {
  var elem = document.createElement(elementName);
  if (typeof attributes === 'object') {
    Object.keys(attributes).forEach(function(attributeName) {
      elem.setAttribute(attributeName, attributes[attributeName]);
    });
  }
  return elem;
}

// load a file image as a data url and callback with this data url
function loadImage(file, callback) {
  var reader = new FileReader();
  reader.onload = function(){
    var dataURL = this.result;
    callback(dataURL);
  };
  reader.readAsDataURL(file);
}

// self explainatory
function createAndInsertNewImageBlock(id, dataURL) {
  var output = create('div', { 'class': 'img_block' });

  // image label, linked to the file input through their for/id attributes
  var label = create('label', { 'for': id, 'class': 'img_label' });
  var img = create('img', { 'class': 'image', src: dataURL });
  label.appendChild(img);
  output.appendChild(label);

  // single file input triggered by the image label, it is hidden
  var input = create(
    'input',
    {
      'type': 'file',
      'class': 'hidden',
      'accept': 'image/*',
      id: id
    }
  );
  // load single data url on change and change the image src
  input.addEventListener('change', function() {
    loadImage(this.files.item(0), function(data) {
      img.src = data;
    });
  });
  output.appendChild(input);

  // delete block button
  var cross = create('div', { 'class': 'cross' });
  cross.addEventListener('click', function() {
    output.remove();
  });
  output.appendChild(cross);

  // insert new image block just before the '+' placeholder
  container.insertBefore(output, placeholder);
}

// handler for the onChange event of the placeholder's file input
function openFiles(evt) {
  var files = evt.target.files;
  for (let i = 0; i < files.length; i++) {
    var file = files.item(i);
    loadImage(file, function(dataURL){
      var count = container.children.length;
      // lame unique id generation for linking label to input
      var id = 'img(' + count + '/' + (Date.now()).toString(16) + ')' + file.name;
      createAndInsertNewImageBlock(id, dataURL);
    });
  };
  
};
#img_container {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}

.image {
  width: 150px;
  margin: 5px;
}

.hidden {
  position: absolute;
  display: none;
  left: -9999px;
}
.img_block {
position: relative;
}
.img_label {
  display: block;
  cursor: pointer;
}

.plus {
  width: 100px;
  height: 100px;
  font-size: 50px;
  font-weight: bold;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #2060FF;
}
.plus:after {
content: '+';
}

.cross {
  width: 15px;
  height: 15px;
  font-size: 20px;
  font-weight: bold;
  background-color: rgba(255,255,255,0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #FF2060;
  position: absolute;
  top: 5px;
  right: 5px;
  cursor: pointer;
}
.cross:hover {
background-color: rgba(255,255,255,0.6);
}
.cross:after {
content: 'x';
}
<div id="img_container">
  <div id="placeholder">
    <label class="img_label" for="placeholder_input">
      <div class="plus"></div>
    </label>
    <input type='file' id="placeholder_input" class="hidden" accept="image/*" onchange='openFiles(event)' multiple>
  </div>
</div>