html5之多文件拖拽上传预览
来源:互联网 发布:进出口业务流程知乎 编辑:程序博客网 时间:2024/04/29 22:57
最近对于html5预览功能很是感兴趣,特地拿出来研究一小下,并以一个小项目举例讲解。
h5中的input有个type=file 就是文件上传控件,有个属性multiple就是h5新增的支持多选上传文件。用法很简单:
<input type="file" multiple />
下面着重探讨一下拖拽上传并预览。
---------------------------------------------------------------------------------------------------------------------------------------------
首先定义我们整个过程中所需要用到的变量以及方法。
var zip_dragFile = { fileInput: null,//html file控件 dragDrop: null,//拖拽敏感区域 upButton: null,//提交按钮 url: "",//ajax地址 fileFilter: [],//过滤后的文件数组 filter: function(files) {//选择文件组的过滤方法 return files; }, onSelect: function() {},//文件选择后 onDelete: function() {},//文件删除后 onDragOver: function() {},//文件拖拽到敏感区域时 onDragLeave: function() {},//文件离开到敏感区域时 onProgress: function() {},//文件上传进度 onSuccess: function() {},//文件上传成功时 onFailure: function() {},//文件上传失败时, onComplete: function() {},//文件全部上传完毕时}
之后定义拖拽方法。h5中新增的拖拽方法说明:dragDrop为拖拽到网页后松开鼠标位置,我们新建一个数组fileFilter存放已经拖拽到页面的图片。
DataTransfer 对象:退拽对象用来传递的媒介,使用一般为Event.dataTransfer。
draggable 属性:就是标签元素要设置draggable=true,否则不会有效果,例如:
<div title="拖拽我" draggable="true">xxx</div>
ondragstart 事件:当拖拽元素开始被拖拽的时候触发的事件,此事件作用在被拖曳元素上
ondragenter 事件:当拖曳元素进入目标元素的时候触发的事件,此事件作用在目标元素上
ondragover 事件:拖拽元素在目标元素上移动的时候触发的事件,此事件作用在目标元素上
ondrop 事件:被拖拽的元素在目标元素上同时鼠标放开触发的事件,此事件作用在目标元素上
ondragend 事件:当拖拽完成后触发的事件,此事件作用在被拖曳元素上
Event.preventDefault() 方法:阻止默认的些事件方法等执行。在ondragover中一定要执行preventDefault(),否则ondrop事件不会被触发。另外,如果是从其他应用软件或是文件中拖东西进来,尤其是图片的时候,默认的动作是显示这个图片或是相关信息,并不是真的执行drop。此时需要用用document的ondragover事件把它直接干掉。
Event.effectAllowed 属性:就是拖拽的效果。
在我们项目中添加监听事件如下:
init: function() { var self = this; if (this.dragDrop) { this.dragDrop.addEventListener("dragover", function(e) { self.funDragHover(e); }, false); this.dragDrop.addEventListener("dragleave", function(e) { self.funDragHover(e); }, false); this.dragDrop.addEventListener("drop", function(e) { self.funGetFiles(e); }, false); } //文件选择控件选择 if (this.fileInput) { this.fileInput.addEventListener("change", function(e) { self.funGetFiles(e); }, false); } //上传按钮提交 if (this.upButton) { this.upButton.addEventListener("click", function(e) { self.funUploadFile(e); }, false); } }//文件拖放funDragHover: function(e) { e.stopPropagation(); e.preventDefault(); this[e.type === "dragover"? "onDragOver": "onDragLeave"].call(e.target); return this;}, //获取选择文件,file控件或拖放funGetFiles: function(e) { // 取消鼠标经过样式 this.funDragHover(e); // 获取文件列表对象 var files = e.target.files || e.dataTransfer.files; //继续添加文件 this.fileFilter = this.fileFilter.concat(this.filter(files)); this.funDealFiles(); return this;},
拖拽时候要检测拖拽图片大小以及格式是否符合规定:
filter: function(files) { var arrFiles = []; for (var i = 0, file; file = files[i]; i++) { if (file.type.indexOf("image") == 0 || (!file.type && /\.(?:jpg|png|gif)$/.test(file.name) /* for IE10 */)){ if (file.size >= 512000) { alert('您这张"'+ file.name +'"图片大小过大,应小于500k'); } else { arrFiles.push(file); } } else { alert('文件"' + file.name + '"不是图片。'); } } return arrFiles;},//选中文件的处理与回调funDealFiles: function() { for (var i = 0, file; file = this.fileFilter[i]; i++) { //增加唯一索引值 file.index = i; } //执行选择回调 this.onSelect(this.fileFilter); return this;},
if ( typeof FileReader === 'undefined' ) { alert( " 您的浏览器未实现 FileReader 接口 " );} else { var reader = new FileReader(); // do sth.}
FileReader 的实例拥有 4 个方法,其中 3 个用以读取文件,另一个用来中断读取。下面的表格列出了这些方法以及他们的参数和功能,需要注意的是 ,无论读取成功或失败,方法并不会返回读取结果,这一结果存储在 result属性中。
方法名 参数 描述
abort none 中断读取
readAsBinaryString file 将文件读取为二进制码
readAsDataURL file 将文件读取为DataURL
readAsText file,[encoding] 将文件读取为文本
readAsText: 该方法有两个参数,其中第二个参数是文本的编码方式,默认值为 UTF-8。这个方法非常容易理解,将文件以文本方式读取,读取的结果即是这个文本文件中的内容。
readAsBinaryString: 这个方法将文件读取为二进制字符串,通常我们将它传送到后端,后端可以通过这段字符串存储文件。
readAsDataURL: 这是例子程序中用到的方法,该方法将文件读取为一段以 data: 开头的字符串,这段字符串的实质就是 Data URI,Data URI是一种将小文件直接嵌入文档的方案。这里的小文件通常是指图像与 html 等格式的文件。点击这里了解更多关于 Data URI 的知识。
3. 事件
FileReader 包含了一套完整的事件模型,用于捕获读取文件时的状态,下面这个表格归纳了这些事件。
事件 描述
onabort 中断时触发
onerror 出错时触发
onload 文件读取成功完成时触发
onloadend 读取完成触发,无论成功或失败
onloadstart 读取开始时触发
onprogress 读取中
文件一旦开始读取,无论成功或失败,实例的 result 属性都会被填充。如果读取失败,则 result 的值为 null ,否则即是读取的结果,绝大多数的程序都会在成功读取文件的时候,抓取这个值。
reader.onload = function () {
this.result // 读取结果
}
代码如下:
onSelect: function(files) { var html = '', i = 0; $("#preview").html('<div class="upload_loading"></div>'); var funAppendImage = function() { file = files[i]; if (file) { var reader = new FileReader() reader.onload = function(e) { html = html + '<div id="uploadList_'+ i +'" class="upload_append_list"><p><strong>' + file.name + '</strong>'+ '<a href="javascript:" class="upload_delete" title="删除" data-index="'+ i +'"> 删除</a><br />' + '<img id="uploadImage_' + i + '" src="' + e.target.result + '"class="upload_image" /></p>'+ '<span id="uploadProgress_' + i + '" class="upload_progress"></span>' + '</div>'; i++; funAppendImage(); } reader.readAsDataURL(file); } else { $("#preview").html(html); if (html) { //删除方法 $(".upload_delete").click(function() { zip_dragFile.funDeleteFile(files[parseInt($(this).attr("data-index"))]); return false; }); //提交按钮显示 $("#fileSubmit").show(); } else { //提交按钮隐藏 $("#fileSubmit").hide(); } } }; funAppendImage();},
至此为止,图片预览效果已经可以实现了,接下来我们要进行预览图片的删除:
//删除对应的文件funDeleteFile: function(fileDelete) { var arrFile = []; for (var i = 0, file; file = this.fileFilter[i]; i++) { if (file != fileDelete) { arrFile.push(file); } else { this.onDelete(fileDelete); } } this.fileFilter = arrFile; return this;},onDelete: function(file) { $("#uploadList_" + file.index).fadeOut();},
接下来我们要自定义一些拖拽上传事件回调(都是样式以及web显示)
onDragOver: function() { $(this).addClass("upload_drag_hover");},onDragLeave: function() { $(this).removeClass("upload_drag_hover");},
至此为止,web端操作已经基本完成,接下来我们就要进行最后一步了--上传:
h5中有个progress方法专门检测上传文件进度:
//文件上传funUploadFile: function() { var self = this; for (var i = 0, file; file = this.fileFilter[i]; i++) { (function(file) { var xhr = new XMLHttpRequest(); if (xhr.upload) { // 上传中(h5的upload对象监听传输事件) xhr.upload.addEventListener("progress", function(e) { self.onProgress(file, e.loaded, e.total); }, false); // 文件上传成功或是失败 xhr.onreadystatechange = function(e) { if (xhr.readyState == 4) { if (xhr.status == 200) { self.onSuccess(file, xhr.responseText); self.funDeleteFile(file); if (!self.fileFilter.length) { //全部完毕 self.onComplete(); } } else { self.onFailure(file, xhr.responseText); } } }; // 开始上传 xhr.open("POST", self.url, true); xhr.setRequestHeader("X_FILENAME", file.name); xhr.send(file); } })(file); }},
在这里利用传统的xmlHttpRequest方法,无论成功失败都进行处理,随后进行结果处理:
onProgress: function(file, loaded, total) { var eleProgress = $("#uploadProgress_" + file.index), percent = (loaded / total * 100).toFixed(2) + '%'; eleProgress.show().html(percent);},onSuccess: function(file, response) { $("#uploadInf").append("<p>上传成功,图片地址是:" + response + "</p>");},onFailure: function(file) { $("#uploadInf").append("<p>图片" + file.name + "上传失败!</p>"); $("#uploadImage_" + file.index).css("opacity", 0.2);},onComplete: function() { //提交按钮隐藏 $("#fileSubmit").hide(); //file控件value置空 $("#fileImage").val(""); $("#uploadInf").append("<p>当前图片全部上传完毕,可继续添加上传。</p>");}
ok,这个小demo到这里就完成了。调用方法:
zip_dragFile = $.extend(zip_dragFile, params);
zip_dragFile.init();
欢迎大家指教。- html5之多文件拖拽上传预览
- html5 文件上传预览
- html5文件上传预览
- HTML5拖拽上传图片预览
- Ext4+Servlet+HTML5实现实时获取文件上传进度、本地预览、文件拖拽上传的相册实例
- Ext4+Servlet+HTML5实现实时获取文件上传进度、本地预览、文件拖拽上传的相册实例
- Ext4+Servlet+HTML5实现实时获取文件上传进度、本地预览、文件拖拽上传的相册实例
- html5-文件:FileReader实现上传前预览
- ajax文件拖拽上传 预览
- HTML5文件拖拽上传
- html5预览上传图片
- html5---图片上传预览
- HTML5 上传前预览
- Html5 上传图片预览
- HTML5上传图片预览
- html5多文件上传预览及进度条 思路
- C# 结合html5 批量上传文件和图片预览
- HTML5使用FileReader预览上传的图片文件
- 内存碎片序列化
- POJ3632 找停车点
- [盘点]苹果发全系电脑新品 Retina版iPad mini面世
- easydialog弹出框Demo
- iPad Air上手体验:更轻薄但不牺牲流畅性
- html5之多文件拖拽上传预览
- 科技公司的奇葩企业文化
- HandlerSocket的perl接口操作方法
- 美国西南航空及Cars.com要求微软撤除与其对应的WebApp
- 【ML】北大标注集,计算所标注集
- 苹果两款新iPad外媒点评汇总:平板向超PC迈进
- 让大家期待已久的黑动漫终于来了,不想错过的话抓紧抢购吧
- android handler线程原理详解
- 我的初恋今天开始