html5+js拖拽上传的那些事
来源:互联网 发布:关于网络直播的作文800 编辑:程序博客网 时间:2024/06/06 01:12
最近搞了个拖拽上传的项目,以为挺简单,做了之后发现里面涉及的东西还是非常多的。这里随性的谈谈其中有意思的地方吧。
拖拽事件
-原生拖拽事件
DragEvent上传是html5的东东,对应的几个事件有
- drag
- dragend
- dragenter
- dragexit
- dragleave
- dragover
- dragstart
- drop
其中常用的有四个:dragenter、dragover、drop、dragend
分别对应的事件为:拖进、拖来拖去、释放鼠标、拖出
换成代码就长这样:
document.addEventListener("dragenter", function( event ) { ...}, false);document.addEventListener("dragover", function( event ) { ...}, false);document.addEventListener("drop", function( event ) { event.preventDefault();//禁止浏览器默认行为 ... return false;//禁止浏览器默认行为}, false);document.addEventListener("dragend", function( event ) { ...}, false);
一般来说,上传在”drop”的时候进行,即在document里松开鼠标,然后可以从event里面拿到dataTransfer.files这个对象,获得用户拖拽的数据。
-jquery封装的拖拽事件
jquery里面的拖拽和原生的有一点点区别,然后附带一个小坑。
$("body").on({ drop:function(e){ //拖后放 e.preventDefault(); //jquery的file要去e.originalEvent里面拿 var files = e.originalEvent.dataTransfer.files; ... }})
似乎是因为在设计时没有封装进去,所以用jquery绑定的drop里的文件要去event的原本event对象——originalEvent里面才能拿到。
啥牛逼的工具都是建立在原生api上的,在这里还是感叹一句,基础知识要学好。
-兼容性
既然是html5的api,对浏览器也会有一定的要求。
针对浏览器的最低兼容性,mdn上给出的数据如下:
遍历文件
-FileList文件
事实上,前文有提到过,上传的文件储存在e.dataTransfer.files中。如果察看它的类型的话会发现这是一个FileList类型。
Object.prototype.toString.call(e.dataTransfer.files);//"[object FileList]"
这种类型专门存放由<input type="file">
上传的数据。
FileList自带一个length属性,以及一个item()方法。它的结构是类似这样的:
dataTransfer.files:{ 0: File, length: 1}
乍一看下挺像一个普通的对象,不过和一般的对象有些区别。访问其中的数据可以使用dataTransfer.files[0]或者dataTransfer.files.item(0)。如果使用for in遍历的话在不同浏览器里会有意想不到问题。
-遍历FileList文件
在此之前,我一直认为dataTransfer.files是一个普通的对象。所以一直使用for in来处理。然而在不同浏览器里有不同的问题。
- 在chrome中使用hasOwnProperty这个方法能够很好地识别出来那些File文件,没有什么问题。(在这里不得不感慨chrome的v8内核真是强大。如果大家都用chrome就省了不知多少事。)
- 在ie/edge浏览器中hasOwnProperty并不会把[0],[1]这些判断为自己的属性。
- 在搜狗浏览器中,hasOwnProperty会把length当做自己的属性。
正确的遍历应该是这样的:
var file;var files = e.dataTransfer.files;for(var i = 0; i < files.length; i++){ file = files [i]; //或者 file = files.item(i); alert(file.name);}
不支持文件夹上传
由于项目只支持文件上传,不支持文件夹上传,因此需要识别出来拖拽的文件是否为文件夹。
-文件属性?
从e.dataTransfer里面并不能很好的区分是否拖拽的文件为文件夹。有这么几个原因:
- 部分文件夹在e.dataTransfer.files里面仍然会显示size
- 文件夹的File里type为”“,但是不加拓展名的文件File里type也为”“
- 在e.dataTransfer里没有找到辨别是否为文件夹的函数
因此没有什么直接的方法去判断。
-FileReader
FileReader是html5的api,用来读取File文件。
它提供了三个读取的方法:
使用方法如下
var fr = new FileReader();fr.readAsBinaryString(file);//fr.readAsDataURL(file);//fr.readAsText(file);fr.onload=function(e){ var data = this.result;}fr.onerror=function(e){ //...}
这三个方法都可以用不同形式读取文件的内容,但是读取文件夹的时候会触发error。因此可以用这个特点去判断上传的文件是否是文件夹。
myFileReader(file,function(result,file){ if(result){ //文件 }else{ //文件夹 }});function myFileReader(file, callback){ if(!window.FileReader){ callback(true,file); return false; } var fr = new FileReader(); fr.readAsDataURL(file); fr.onload=function(e){ callback(true,file); } fr.onerror=function(e){ callback(false,file); } return true;};
另外,文件越大,读取的速度越慢。一般来说,如果拖拽的是文件夹,其File里面的size属性大小不会超过5M。因此可以先用这个属性刷掉一波非文件夹,增加预处理的速度。
- html5+js拖拽上传的那些事
- html5+js拖拽上传
- HTML5必须知道的那些事
- 【缓存\性能】HTML5缓存的那些事
- HTML5的那些事儿
- HTML5文件拖拽上传
- html5拖拽上传图片
- html5 video 那些事
- html5 js 图片上传预览
- HTML5上传文件ajaxfileupload.js
- 基于html5、JS实现的拍照上传图片
- PHP+JS+HTML5+Flash网页上传超大文件的解决方案
- 基于html5 JS实现的拍照上传图片
- JS学习32:html5拖拽图片批量ajax无刷新进度上传
- js,html5画图,js截图,ajax上传
- Html5的文件上传
- HTML5文件实现拖拽上传
- HTML5开发 拖拽文件上传
- 【grunt整合版】30分钟学会使用grunt打包前端代码
- PHP 10问——PART 3
- 在python中调用grass的模块
- IIS6.0 应用程序池Web园导致Session丢失(转改添加)
- 在Hyper-V环境下进行安装Centos7系统
- html5+js拖拽上传的那些事
- Android应用性能优化系列视图篇——恼人的分割线留白解决之道
- 关于我自己的
- HTML基础样式(三)
- android studio的配置版本号和名称
- java 实现WebService 以及不同的调用方式
- Xcode7支持iOS10设备的编译
- tomcat启动异常
- scala的类和对象