走进HTML5-实现网站中常见的拖拽上传文件

欢迎关注个人我的博客分享一些前端技术、面试题、面试技巧等前端

当咱们学习了 HTML 提供的原生拖放(drag & drop)后,是时候想想这个东西能够用来做什么能够在何时使用使用的场景等等git

场景分析

当咱们在注册成功一个帐户时,通常网站会让咱们上传咱们的用户头像,或者在实名认证的时候会涉及到身份证图片上传到等,这时候咱们可使用input提供的file属性进行选择本地文件进行上传。github

实名认证

咱们再想一下,当在电脑端的状况下,当用户打开文件选择框时再寻找图片对应的文件夹,再进行选取文件的时候是否是会有点麻烦呢?咱们可不可让用户找到图片文件,直接引入实现上传呢?答案是能够的。web

怎么作

通过这些分析后,咱们能够尝试使用 HTML5 提供的拖拽,使得目标元素增长读取文件功能,而后使用 ajax 实现图片上传。面试

谈一谈咱们须要使用到的技术:ajax

  • Drag & Drop: HTML5 基于拖拽的事件机制
  • File API: 能够很方便的让 Web 应用访问文件对象,File API 包括 FileList、Blob、File、FileReader、URI scheme,本文主要讲解拖拽上传中用到的 FileList 和 FileReader 接口。
  • FormData: FormData 是基于 XMLHttpRequest Level 2 的新接口,能够方便 web 应用模拟 Form 表单数据,最重要的是它支持文件的二进制流数据,这样咱们就可以经过它来实现 AJAX 向后端发送文件数据了。

HTML5 拖拽事件

关于 Drag & Drop 拖拽事件,以前我写过一篇专门介绍的文章,HTML5-拖拽,你们有兴趣的话能够点击连接查看,我在这里就不在多啰嗦了~下面直接出拖拽上传的简要代码示例后端

var oDragWrap = document.body;

//拖进
oDragWrap.addEventListener(
  "dragenter",
  function(e) {
    e.preventDefault();
  },
  false
);

//拖离
oDragWrap.addEventListener(
  "dragleave",
  function(e) {
    dragleaveHandler(e);
  },
  false
);

//拖来拖去 , 必定要注意dragover事件必定要清除默认事件
//否则会没法触发后面的drop事件
oDragWrap.addEventListener(
  "dragover",
  function(e) {
    e.preventDefault();
  },
  false
);

//扔
oDragWrap.addEventListener(
  "drop",
  function(e) {
    dropHandler(e);
  },
  false
);

var dropHandler = function(e) {
  //将本地图片拖拽到页面中后要进行的处理都在这
};
复制代码

获取文件数据 HTML5 File API

File API 中的 FileReader 接口,做为 File API 的一部分,FileReader 专门用来读取文件。咱们在这里主要介绍一些 File API 中的 FileList 接口,它主要经过两个途径获取本地文件列表,一是<input type="file"/>的表单形式,另外一种则是e.dataTransfer.files拖拽事件传递的文件信息。数组

var fileList = e.dataTransfer.files;
复制代码

使用 files 方法将会获取到拖拽文件的数组形式的数据,每一个文件占用一个数组的索引,若是索引不存在文件数据,将返回 Null。能够经过length属性获取文件的数量。服务器

var fileNum = fileList.length;
复制代码

拖拽上传须要注意的是须要判断两个条件app

  1. 拖拽的是文件而不是页面的元素
  2. 拖拽的是图片而不是其余类型的文件,能够经过 file.type 属性获取文件的类型
// 检测是不是拖拽文件到页面的操做
if (fileList.length === 0) {
  return;
}

// 检测文件是否是图片
if (fileList[0].type.indexOf("image") === -1) {
  return;
}
复制代码

下面咱们看看结合以前的拖拽事件,来实现拖拽图片并在页面中预览

var dropHandler = function(e) {
  e.preventDefault(); //获取文件列表

  var fileList = e.dataTransfer.files;

  //检测是不是拖拽文件到页面的操做
  if (fileList.length == 0) {
    return;
  }

  //检测文件是否是图片
  if (fileList[0].type.indexOf("image") === -1) {
    return;
  }

  //实例化file reader对象
  var reader = new FileReader();
  var img = document.createElement("img");

  reader.onload = function(e) {
    img.src = this.result;
    oDragWrap.appendChild(img);
  };
  reader.readAsDataURL(fileList[0]);
};
复制代码

n34B6S.gif

当完成以上操做后,相信你能够成功的完成了拖拽图片预览的操做。当你查看 img 标签时会发现,img的src属性是一个超长的文件二进制数据,当你须要不少这种的img元素时,建议将展现区域脱离文档流,让其绝对定位减小页面的 reflow

AJAX 上传图片

既然已经获取到拖拽到web页面中的图片数据了,下一步就是将其发送到服务器端。

总结

  1. 监听拖拽: 监听页面元素的拖拽事件,包括: dragenterdragoverdragleavedrop,必定要将dragover的默认事件取消掉,否则没法触发drop事件。如需拖拽页面里面的元素,须要给其添加属性draggable="true"
  2. 获取拖拽文件: 在 drop 事件触发后经过e.dataTransfer.files获取拖拽文件列表,必定要将drop的默认事件取消掉,不然会默认打开文件length属性获取文件数量,type属性获取文件类型
  3. 读取图片数据并添加预览图: 实例化FileReader对象,经过其readAsDataURL(file)方法获取文件二进制流,并监听其onload事件,将e.result赋值给img的src属性,最后将图片添加到DOM中
  4. 发送图片数据

但愿对读完本文的你有帮助、有启发,若是有不足之处,欢迎批评指正交流!

欢迎关注个人我的博客分享一些前端技术、面试题、面试技巧等

辛苦整理良久,还望手动点赞鼓励~


'摘抄'不是单纯的“粘贴->复制”,而是眼到,手到,心到的一字一句敲打下来。

博客声明:全部转载的文章、图片仅用于做者本人收藏学习目的,被要求或认为适当时,将标注署名与来源。若不肯某一做品被转用,请及时通知本站,本站将予以及时删除。

相关文章
相关标签/搜索