转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/31513065

上一篇已经实现了这个项目的整体的HTML和CSS:

HTML5 CSS3 经典案例:无插件拖拽上传图片 (支持预览与批量) (一)

这篇博客直接在上篇的基础上完成,最终效果:

效果图1:

效果图2:

好了,请允许我把图片贴了两遍,方便大家看效果了~

可以看出我们的图片的li的html其实还是挺复杂的,于是我把html文档做了一些修改:

<span style="font-size:12px;"><body>

<div id="uploadBox">
</div> <div id="template" class="hidden">
<li>
<img src=""/>
<span class="progress"></span>
<span class="percentage"></span>
</li>
</div>
</body></span>

可以看到我把li的显示,独立写到了一个div#template,默认是hidden的,这样做的好处是什么呢?避免我们每上传一个文件,在js中出现大量的创建元素与赋属性的代码,一般设计比较复杂的html元素的生成,建议使用这种方式,可以简化代码,也利于我们代码的后期维护。

Js代码:

<span style="font-size:12px;">/**
* User: zhy
* Date: 14-6-16
* Time: 下午11:06
*/
var ZhangHongyang = {};
ZhangHongyang.html5upload = (function ()
{
var _ID_UPLOAD_BOX = "uploadBox";
var _CLASS_PROGRESS = "progress";
var _CLASS_PERCENTAGE = "percentage"; var _tip_no_drag = "将文件拖拽至此区域,即可上传!";
var _tip_drag_over = "释放鼠标立即上传!"; var _uploadEle = null; /**
* 初始化对象与事件
* @private
*/
function _init()
{
_uploadEle = document.getElementById(_ID_UPLOAD_BOX);
_uploadEle.ondragenter = _onDragEnter;
_uploadEle.ondragover = _onDragOver;
_uploadEle.ondragleave = _onDragLeave;
_uploadEle.ondrop = _onDrop;
_setStatusNoDrag(); }; /**
* 正在拖拽状态
* @private
*/
function _setDragOverStatus()
{
if (_checkContatinsElements())return;
_uploadEle.innerText = _tip_drag_over;
_uploadEle.style.border = "2px dashed #777";
$(_uploadEle).css({lineHeight: $(_uploadEle).height() + "px"});
} /**
* 初始化状态
* @private
*/
function _setStatusNoDrag()
{
if (_checkContatinsElements())return;
_uploadEle.innerText = _tip_no_drag;
_uploadEle.style.border = "2px dashed #777";
$(_uploadEle).css({lineHeight: $(_uploadEle).height() + "px"});
} /**
* 上传文件
* @private
*/
function _setDropStatus()
{ if (_checkContatinsElements())return;
_uploadEle.innerText = "";
_uploadEle.style.border = "1px solid #444";
$(_uploadEle).css({lineHeight: "1em"});
$(_uploadEle).append("<ul></ul>"); }; /**
* 判断是否已经上传文件了
* @private
*/
function _checkContatinsElements()
{
return !!$(_uploadEle).find("li").size(); }
/**
* 当ondragenter触发
* @private
*/
function _onDragEnter(ev)
{
_setDragOverStatus();
}
/**
* 当ondargmove触发
* @private
*/
function _onDragOver(ev)
{
//ondragover中必须组织事件的默认行为,默认地,无法将数据/元素放置到其他元素中。
ev.preventDefault(); }
/**
* 当dragleave触发
* @private
*/
function _onDragLeave(ev)
{
_setStatusNoDrag();
} /**
* ondrop触发
* @private
*/
function _onDrop(ev)
{
//drop 事件的默认行为是以链接形式打开,所以也需要阻止其默认行为。
ev.preventDefault();
_setDropStatus(); //拿到拖入的文件
var files = ev.dataTransfer.files;
var len = files.length;
for (var i = 0; i < len; i++)
{
//页面上显示需要上传的文件
_showUploadFile(files[i]);
}
}
/**
* 页面上显示需要上传的文件
* @private
*/
function _showUploadFile(file)
{
var reader = new FileReader();
// console.log(file)
// console.log(reader); //判断文件类型
if (file.type.match(/image*/))
{
reader.onload = function (e)
{
var formData = new FormData(); var li = $("#template li").clone();
var img = li.find("img");
var progress = li.find(".progress");
var percentage = li.find(".percentage");
percentage.text("0%");
img.attr("src", e.target.result);
$("ul", $(_uploadEle)).append(li);
$(_uploadEle).find("li").size() == 10 && $(_uploadEle).width(($(_uploadEle).width() + 8) + "px").css("overflow", "auto");
formData.append("uploadFile", file); //上传文件到服务器
_uploadToServer(formData, li, progress, percentage); };
reader.readAsDataURL(file);
}
else
{
console.log("此" + file.name + "不是图片文件!");
}
} /**
* 上传文件到服务器
* @private
*/
function _uploadToServer(formData, li, progress, percentage)
{
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:8080/strurts2fileupload/uploadAction", true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest', 'Content-Type', 'multipart/form-data;'); //HTML5新增的API,存储了上传过程中的信息
xhr.upload.onprogress = function (e)
{
var percent = 0;
if (e.lengthComputable)
{
//更新页面显示效果
percent = 100 * e.loaded / e.total;
progress.height(percent );
percentage.text(percent + "%");
percent >= 100 && li.addClass("done");
}
};
xhr.send(formData);
} //把init方法公布出去
return{
init: _init } })();
</span>

注释写得很详细,这次没有直接使用字面量创建对象,因为我不希望使用者可以访问所有的方式和变量,使用了简单的闭包,可以看出几乎所有的方法和变量都是_开头,是因为我认为它们是私有的,我也没有公布出来,唯一公布的就是init方法,供使用者调用。整体方法也使用了命名空间,这样和其他伙伴写的js基本不做造成变量相同的问题。


上面的js中用到了HTML FileApi,这里介绍一下:

1、File对象也就是我们上面使用的:
File
  1. lastModifiedDate: Thu
    Dec 26 2013 18:45:08 GMT+0800 (中国标准时间)
  2. name: "yt_key.png"
  3. size: 45524
  4. type: "image/png"
  5. webkitRelativePath: ""
  6. __proto__: File

可以看到包含上面的一些属性,也就是说,如果使用支持html5的浏览器,给input=type设置onchange事件,用户选择图片或者文件后,就可以做出图片的显示或者文件大小和类型的判断。


2、FileReader主要用于异步读取文件内容,注意是异步的,上例我们使用了它的readAsDataURL的方法,关于DataUri的知识可以自己去百度下。
另外还提供了:readAsText用于读取文本;readAsArrayBuffer和readAsBinaryString方法;
还提供了一些事件:onloadstart, onload, onprogress ,onerror , onloaded , onabort 有兴趣的可以去一个一个查看。

最后页面调用,大功告成:

<span style="font-size:12px;">    <script type="text/javascript" src="jquery-1.8.3.js"></script>
<script type="text/javascript" src="js/html5upload.js"></script> <script type="text/javascript"> window.onload = function ()
{
ZhangHongyang.html5upload.init();
}
; </script></span>

欢迎大家指点~

源码点击下载

版权声明:本文为博主原创文章,未经博主允许不得转载。

HTML5 CSS3 经典案例:无插件拖拽上传图片 (支持预览与批量) (二)的更多相关文章

  1. 可拖拽和带预览图的jQuery文件上传插件ssi-uploader

    插件描述:ssi-uploader是一款带预览图并且可以拖拽文件的jQuery ajax文件上传插件.该文件上传插件支持AJAX,支持多文件上传,可控制上的文件格式和文件大小,提供各种回调函数,使用非 ...

  2. HTML5&CSS3经典动态表格

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. HTML5实战与剖析之原生拖拽(四可拖动dragable属性和其他成员)

    可拖动dragable属性 之前我们已经为大家介绍过几篇有关HTML5中原生拖拽的相关知识了.今天为大家介绍HTML5拖拽中的其他一些小东东,闲话不多说赶快一起看看吧. 在默认情况下,链接.文本和图像 ...

  4. HTML5实战与剖析之原生拖拽(一拖拽历史概述)

    提起拖拽,我就想起了在JavaScript培训的时候一个非常好玩的效果,那就是拖拽了.可以用鼠标任意拖拽着一个物体到任何你想去的地方. 最早拥有JavaScript拖拽功能的是IE4浏览器.当时,网页 ...

  5. h5拖拽上传图片

    h5实现拖拽上传图片 本文将为大家介绍如何通过js实现拖拽上传图片. 首先我们要禁用调浏览器默认的拖拽事件: window.onload = function(){ //拖离 document.add ...

  6. js拖拽上传图片

    有时候,在开发中,需要遇到拖拽上传图片的需求,即从磁盘选中一张或多张图片,然后按着鼠标把图片拖动到页面上指定的区域,实现图片的上传. 1.后端上传图片的接口 我是之前用vue写一个简单的后台系统的时候 ...

  7. 多文件上传插件Stream,是Uploadify的Flash版和Html5版的结合,带进度条,并支持html5断点续传(附件上传),拖拽等功能

    是根据某网的文件上传插件加工而来,支持不同平台(Windows, Linux, Mac, Android, iOS)下,主流浏览器(IE7+, Chrome, Firefox, Safari, 其他) ...

  8. HTML5 02. 多媒体控件、拖拽事件、历史记录、web存储、应用程序缓存、地理定位、网络状态

    多媒体 video:是行内块(text-align: center; 对行内块适用) <figure></figure>: 多媒体标签 : <figcaption> ...

  9. JQuery+HTML5+CSS3制作时间轴插件,支持响应式布局

    一.效果图预览 (图一) (图二) 附注说明: 图一是浏览器宽度像素大于560px下的展示效果,图二是在浏览器宽度像素小于560px下的展现效果.使用的是CSS3的Media Query(媒体查询)实 ...

随机推荐

  1. 安装docker及配置Android开发环境

    安装docker 官方原来的安装docker的脚本https://get.docker.com/已经过时,现在使用的是https://get.docker.com/,命令如下: curl -s htt ...

  2. IOS9关于搜索的认识和实现

    原文链接 : iOS 9 App Search Tutorial: Introduction to App Search 原文作者 : Chris Wagner 译文出自 : 开发技术前线 www.d ...

  3. 关于Block的使用和5点注意事项

    一.概念 首先需要了解的是Block是一个代码块,是一个变量的形式存在的. 二.构成了解 我们需要在函数中声明block,因为是变量的形式,而且存在静态变量形式 类型1:  NSString* (^b ...

  4. remove Nth Node from linked list从链表中删除倒数第n个元素

    Given a linked list, remove the nth node from the end of list and return its head. For example, Give ...

  5. 《深入理解java虚拟机》读书笔记1--java内存区域

    Java内存管理 本文主要介绍Java虚拟机运行时的内存区域是如何划分的.Java对象的创建过程.Java对象的内存布局.Java对象的访问定位 一:运行时区域划分 主要可以分为以下 几个: 程序计数 ...

  6. access窗体最大化到软件大小

    Private Sub Form_Load()DoCmd.ShowToolbar "Ribbon", acToolbarNo '窗体最大化,占满软件最 End Sub

  7. EF Core使用SQL调用返回其他类型的查询

    假设你想要 SQL 本身编写,而不使用 LINQ. 需要运行 SQL 查询中返回实体对象之外的内容. 在 EF Core 中,执行该操作的另一种方法是编写 ADO.NET 代码,并从 EF 获取数据库 ...

  8. DDD实战进阶第一波(九):开发一般业务的大健康行业直销系统(实现经销商上下文仓储与领域逻辑)

    上篇文章主要讲述了经销商上下文的需求与POCO对象,这篇文章主要讲述该界限上下文的仓储与领域逻辑的实现. 关于界限上下文与EF Core数据访问上下文参考产品上下文相应的实现,这里不再累述. 因为在经 ...

  9. Vue 仿B站滑动导航

    仿照B站制作的滑动导航功能,进行了部分优化,例如可定制默认选中元素,并将选中元素居中显示,可动态更改数据,可定制回调函数取的下标和选中元素内容,可根据需求制作N级联动 已开发成插件,使用方法与源码请前 ...

  10. eclipse中maven下载不了私服上面的第三方包问题

    问题描述在nexus中上传了第三方jar包,在本地项目中添加了引用,但就是下载不下来. 转载文章 1. 打开windows -> preferences -> maven,勾选如图所示 2 ...