今天晚上花了几个小时的功夫做了一个相册,类似于QQ空间的文件上传,不过我用的Ext+HTML5等新的技术,结合Servlet上传文件。有几个特点:
- 文件拖拽上传
- 实时获取上传进度
- 本地预览
- 与Ext结合起来
说了这么多,还是贴几张图给大家吧!!
这个是没有做任何操作时候的窗口
拖动图片的时候,提示将图片拖动到指定的区域
这个是拖拽进去后,生成了本地预览,并有相应的详细信息
这个是上传成功后显示的信息。这里可能是本地的原因,一下子就上传完了,没有体现出百分比来。大概就是这个样子了!下面说下实现:首先构建Ext窗口://创建相册窗口 var win = Ext.create('Ext.window.Window', { title : 'Ext相册', width : 700, height : 400, iconCls : 'ablum', layout : 'fit', plain : false, items : [view], buttons : [{ text : '上传', //上传按钮 handler : upload, iconCls : 'upload' }, { text : '清空', handler : function() { store.removeAll(); }, iconCls : 'clear' }] }); win.show();
创建像是图片的容器://创建图片数据模型 ,数据源需要 var PhotoModel = Ext.define('ImageModel', { extend : 'Ext.data.Model', fields : [{name : 'name'}, {name : 'type'}, {name : 'size', type : 'float'}, {name : 'lastmod', type : 'date',dateFormat : 'timestamp'}, {name : 'file'}, {name : 'src'}] }); //创建数据源 var store = Ext.create("Ext.data.Store", { model : PhotoModel }); var ddtip; //图片提示模板 var tiptpl = '名称:{0}<br/>' + '类型:{1}<br/>' + '大小:{2}<br/>' + '修改时间:{3}<br/>' //创建图片存放的容器 var view = Ext.create('Ext.view.View', { store : store, //指定数据源 tpl : [ //设置展示模板 '<tpl for=".">', '<div class="thumb-wrap" id="{name}">', '<div class="upload-progress">0%</div>', '<div class="thumb"><img src="{src}"></div>', '<span>{name}</span></div>', '</tpl>', '<div class="x-clear"></div>'], style : { backgroundColor : '#FFFFFF', fontFamily : '微软雅黑' }, multiSelect : true, trackOver : true, overItemCls : 'x-item-over', itemSelector : 'div.thumb-wrap', emptyText : '没有显示的相片', autoScroll : true, listeners : { 'afterrender' : function() { //创建用户拖拽提示 ddtip = view.el.createChild({ tag : 'div', cls : 'dd-tip', html : '请将图片拖动到这里' }); //创建相片浮动提示 Ext.create('Ext.tip.ToolTip', { target : view.el, delegate : view.itemSelector, trackMouse : true, renderTo : Ext.getBody(), anchor : 'right', listeners : { beforeshow : function(tip) { var record = view .getRecord(tip.triggerElement); tip.update(Ext.String.format( tiptpl, record .get('name'), record.get('type'), record .get('size'), Ext.Date.format( record.get('lastmod'), 'Y年m月d日 H时i分'))); } } }); } } });
添加监听页面拖拽事件://给body添加事件,如果有拖拽的话提示用户拖拽到指定区域 Ext.getBody().on('dragover', function(e) { ddtip.show(); }); //当用户拖拽离开时隐藏提示信息 Ext.getBody().on('dragleave', function(e) { ddtip.hide(); }); //当用户拖拽到指定区域时,隐藏提示信息 view.el.on('dragenter', function(e) { e.stopPropagation(); e.preventDefault(); ddtip.hide(); view.el.highlight(); }); //当用户拖拽离开指定区域时显示提示信息 view.el.on('dragleave', function(e) { e.stopPropagation(); e.preventDefault(); ddtip.show(); }); //很关键!!当用户拖拽文件并放下的时候触发时间 view.el.dom.ondrop = function(e) { e.stopPropagation(); e.preventDefault(); ddtip.hide();//隐藏提示信息 //处理用户拖拽过来的文件 process(e.dataTransfer.files); };
处理用户拖拽过来的文件:function process(files) { var count = 0; for (var i = 0; i < files.length; i++) { var file = files[i];//这个一个File对象 //创建一个相片数据实例,保存名称,大小,类型,修改日期,文件等信息 var photo = Ext.ModelManager.create({ name : file.fileName, size : file.fileSize, type : file.type, file : file, lastmod : file.lastModifiedDate }, PhotoModel); //添加到数据源中,这时候容易会发生相应的变化 store.add(photo); //通过FileReader对象获取预览 var reader = new FileReader(); //当读取完成之后执行的回调 reader.onload = (function(p) { return function() { count++; //将获取到的Base64格式的图片数据,存放起来 p.data.src = this.result; if (count == files.length) { //当所有图片都加载完了之后,渲染图片 view.refresh(); } } })(photo);//这个地方利用了JS的闭包原理 //读取图片 reader.readAsDataURL(file); } }
处理上传方法:function upload(){ //执行上传 store.each(function(photo){//遍历数据源的数据 var progress = Ext.get(view.getNode(photo)).down('div.upload-progress');//显示进度信息 progress.show(); var xhr = new XMLHttpRequest(); //初始化XMLHttpRequest xhr.open('post', 'upload', true); xhr.upload.onprogress = function(p) { //添加数据上传进度,获取实时的上传进度 return function(e) { if (e.lengthComputable) { var percentage = Math.round((e.loaded * 100) / e.total); progress.update(percentage + "%"); } } }(progress); xhr.upload.onload = function(p) { //当上传完之后执行的回调函数 return function(e) { progress.update("上传成功!"); } }(progress); var fd = new FormData(); //这里很关键,初始化一个FormData,并将File文件发送到后台 fd.append("file", photo.data.file); xhr.send(fd); }); }
Servlet实现文件上传的代码:@SuppressWarnings("unchecked") public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path = request.getSession().getServletContext().getRealPath("\\upload"); DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); try { List<FileItem> list = (List<FileItem>) upload.parseRequest(request); for (FileItem fileItem : list) { String fileName = fileItem.getName(); File file = new File(path + "\\" + fileName); fileItem.write(file); fileItem.delete(); } } catch (Exception e) { e.printStackTrace(); } }
就这样,这个相册实例就完成了 !
------------------------------------------------------------------------------分割线---------------------------------------------------------------------------------
2012-05-14更新:
- 增加了通过资源管理器选择文件功能
- 修复上传进度显示BUG
- 增加相片右键菜单
- 上传更改为上传全部项和上传选中项
- 增加图片浏览器功能
- 图片浏览器支持拖动、双击最大化/还原、更改尺寸
- 图片浏览器支持对数据源里面的图片进行导航
- 图片浏览器图片的放大和缩小
由于更新的比较仓促,写的代码质量不是很高,应该将图片浏览器封装成一个对象,并且图片旋转的功能没有完成。这些工作就留给大家伙自己实现吧,图片旋转的代码网上都有。贴图给大家:
通过点击添加按钮选取文件
相片右键菜单
图片查看器,双击相片可以启动。支持图片放大,导航!确定只能在chrome下运行,在firefox下运行有错,不是不能调,只是懒得调了!源码等会会放到下载区里面,只是CSDN有延迟,找不到链接!
---------------------------------------------------------------------------------------------分割线-------------------------------------------------------------------------------------------
大家测试最好用最新版的Google Chrome浏览器。
Ext还能做什么?只有想不到的,没有做不到了,进入http://blog.csdn.net/leecho571/article/details/8207102感受Ext带来的新的体验在chrome下运行有效,firefox还在测试,IE忽略不计!!讨厌IE!!
http://download.csdn.net/detail/leecho571/4657009(2012-05-14版实例)
最后打下小广告,
看文章评论一下是美德,你的评论是我最大的动力!!
Ext4+Servlet+HTML5实现实时获取文件上传进度、本地预览、文件拖拽上传的相册实例...
最新推荐文章于 2023-11-16 21:49:14 发布