上传图片实时预览

引入

当使用<input type=file>上传图片文件时,如何在上传到服务器以前,在本地进行预览?html

FileReader 对象

FileReader对象容许Web应用程序异步读取用户计算机上的文件。使用new建立一个FileReader实例对象:前端

let fileReader = new FileReader();

属性

  • error:在读取时发生的错误
  • readyState:fileReader当前状态
  • result:读取到的文件内容,只有在读取操做完成后有效

方法

  • abort():终止读取操做
  • readAsDateURL():读取文件中的内容,读取完成后调用onloadend方法,结果result中包含一个data:URL格式的字符串表示文件内容(针对图片就是base64格式的字符串)

事件处理程序

  • onabort:读取被终止时被调用
  • onerror:读取错误时调用
  • onload:读取成功时调用
  • onloadend:读取完成时调用,不管成功失败, 在onloadonerror后调用
  • onloadstart:读取开始前调用
  • onprogress:读取过程当中周期调用、

兼容性

image

使用FileReader对象预览图片

  • <input>onchange事件中获取上传的图片对象
  • 使用<input>event.target.files获取上传对象的类数组对象,每一项的name属性对应文件名
  • <input>中增长multiple属性,上传多个文件
  • 建立FileReader对象,并经过readAsDateURL()方法,传入要预览的文件对象,在onload回调函数中对FileReader对象的result进行处理

代码:

预览多张图片chrome

<body>
<label><input type="file" id="file" multiple></label>
<div id="preview" class="preview">
  <img id="img" src="default.png">
</div>
</body>
<script>
  'use strict';
  let input = document.querySelector('#file'),
    wrapper = document.querySelector('#preview'),
    img = document.querySelector('#img');

  function preview(files) {
    Object.keys(files).forEach(function (file) {
      let fileReader = new FileReader();
      fileReader.readAsDataURL(files[file]);
      fileReader.onload = function () {
        img.src = fileReader.result;
        img.title = files[file].name;
      };
    })
  }

  input.onchange = function (e) {
    let files = e.target.files;
    preview(files)
  };
</script>

拖拽预览

不经过点击事件而是经过将图片拖拽到指定区域实现预览。segmentfault

在拖放过程当中会触发的事件:数组

  • 在源元素上触发的事件(须要设置 draggable 属性)浏览器

    • ondragstart:开始拖动时触发
    • ondrag:拖动时触发
    • ondragend:拖动完成时触发
  • 释放时触发的事件安全

    • ondragenter:进入容器范围时触发
    • ondragover:拖动时触发(触发间隔350毫秒)
    • ondragleave:离开容器范围时触发
    • ondrop:拖动过程当中,释放鼠标按键时触发

显然这里须要使用的是 ondrop 事件,可是须要注意,使用ondrop 事件须要阻止浏览器默认行为,不然不会触发服务器

document.addEventListener("drop", function(e) { //释放
  e.preventDefault();
});
document.addEventListener("dragenter", function(e) { //拖进
  e.preventDefault();
});
document.addEventListener("dragleave", function(e) { //拖离
  e.preventDefault();
});
document.addEventListener("dragover", function(e) { //拖来拖去
  e.preventDefault();
});

而后在 ondrop 事件中触发上面的函数就能够实现图片预览了。注意,`inputonchange 事件获取文件对象是 e.target.files,而 drop 事件则是 e.dataTransfer.filesapp

window.URL.createObjectURL()

也能够经过这个方法来实现图片的预览异步

URL.createObjectURL() 静态方法会建立一个 DOMString,这个新的URL 对象表示指定的 File 对象或 Blob 对象。

在每次调用 createObjectURL() 方法时,都会建立一个新的 URL 对象,即便你已经用相同的对象做为参数建立过。当再也不须要这些 URL 对象时,每一个对象必须经过调用 URL.revokeObjectURL() 方法来释放。浏览器会在文档退出的时候自动释放它们,可是为了得到最佳性能和内存使用情况,你应该在安全的时机主动释放掉它们。
// 使用 createObjectURL
function preview2(files) {
  Object.keys(files).forEach(function(file) {
    img.src = window.URL.createObjectURL(files[file]);
  })
}

区别

因为 URL.createObjectURL() 是浏览器自身的接口,貌似性能会更好一点

而且可能比fileReader对IE的兼容性好一些,问题少一些?

不过能够两者选择使用吧,多一个选择不是坏事

参考

相关文章
相关标签/搜索