今天晚上花了几个小时的功夫做了一个相册,类似于QQ空间的文件上传,不过我用的Ext+HTML5等新的技术,结合Servlet上传文件。有几个特点:
创建像是图片的容器:
添加监听页面拖拽事件:
处理用户拖拽过来的文件:
处理上传方法:
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!!