HTML5 拖拽上传

 写了个拖拽上传的效果。

说明:默认情况下的事件对象是body,就是可以直接将图片拖到浏览器窗口上,事件对象也可以是其它HTML元素,只需将该元素的ID赋给target就行了,另外

    也可以是文件域(将下面的HTML代码里的注释去掉就可以查看效果)

效果图:

HTML:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3     <head>
 4         <meta charset="utf-8" />
 5         <link rel="stylesheet" type="text/css" media="all" href="ajaxFileUpload2.css"/>
 6     </head>
 7     <body>
 8         <!--<input type="file" id="fielUpload" name="fielUpload" multiple/>-->
 9         <div style="height:2000px;"></div>
10     <script src="ajaxFileUpload2.js"></script>
11     <script>
12         ajaxUpload({
13             //默认情况下的事件对象是body,直接将图片拖到浏览器中就可以了
14             //也可以设置事件对象为HTML元素,target为元素ID就行了
15             //也可以是文件域
16             //target:'fielUpload',
17             url:'result3.php',
18             thumbWidth:220,
19             thumbHeight:138,
20             success:function(xhr){
21                 var data = xhr.responseText;
22                 console.log(decodeURIComponent(data));
23             },
24             callback:function(){
25                 console.log('done!')
26             }
27         });
28     </script>
29     </body>
30 </html>

JS:

  1 /**
  2  * @author Administrator
  3  */
  4 (function(win){
  5     var doc = win.document,db = doc.body,oFiles=[];
  6     var isOpera=/opera(\/| )(\d+(\.\d+)?)(.+?(version\/(\d+(\.\d+)?)))?/i.test(navigator.userAgent) ?   ( RegExp["\x246"] || RegExp["\x242"] ) : false;
  7     var ajaxUpload = function(opts){return new ajaxUpload.prototype.init(opts);};
  8     ajaxUpload.prototype = {
  9         constructor:ajaxUpload,
 10         init:function(opts){
 11             var set = extend({
 12                 target:'body',
 13                 boxWidth:950,
 14                 boxHeight:500,
 15                 thumbWidth:200,
 16                 thumbHeight:200,
 17                 url:'',
 18                 callback:function(){}
 19             },opts||{});
 20             var target = set.target === 'body' ? db : $(set.target);
 21             if(target.type == 'file'){
 22                 target.addEventListener('change',handleChange(set),false);
 23             }else{
 24                 target.addEventListener('dragenter',function(e){ e.preventDefault();},false);
 25                 target.addEventListener('dragover',function(e){ e.preventDefault();},false);
 26                 target.addEventListener('drop',function(e){e.preventDefault();handleDrop(e,set);},false);
 27             };
 28         }
 29     };
 30     ajaxUpload.prototype.init.prototype = ajaxUpload.prototype;
 31     win.ajaxUpload = ajaxUpload;
 32     /**********************************************************************************/
 33     function handleChange(set){
 34        return function(){
 35            handleFiles(this.files,set);
 36        };  
 37     };
 38     function handleDrop(e,set){
 39         handleFiles(e.dataTransfer.files,set);
 40     };
 41     function handleFiles(files,set){
 42         var fragment = createContent(files);
 43         //如果已经有文件了,则只需要追加就可以了
 44         if(!handleFiles.box || !handleFiles.ul){
 45             handleFiles.box = createWindow(set);
 46             handleFiles.ul = createEl('<ul id="imgList"></ul>');
 47             handleFiles.box.content.appendChild(handleFiles.ul);
 48             db.addEventListener('click',handleControl,false);
 49             handleFiles.box.btnUpload.addEventListener('click',handleUpload(set),false);
 50             handleFiles.box.btnCancel.addEventListener('click',handleCancel,false);
 51             handleFiles.box.close.addEventListener('click',handleClose,false);
 52         }
 53         handleFiles.ul.appendChild(fragment);
 54     };
 55     function createContent(files){
 56         var item,imgBox,img,reader,editRemark,file,fragment = doc.createDocumentFragment();
 57         oFiles = merge(oFiles,files);
 58         each(files,function(i){
 59             file = this;
 60             if(!(/image\/.*/.test(file.type))) return;
 61             item = createEl('<li class="sbi_item"><p class="remark"></p><span class="progressbox"><em class="progress"></em></span><span class="control"><a class="edit" href="javascript:void(0)">备注</a><a class="del" href="javascript:void(0)">删除</a></span></li>',fragment);
 62             editRemark = createEl('<textarea class="editRemark"></textarea>',item);
 63             imgBox = createEl('<span class="img_preview"></span>',item);
 64             img = createEl('<img src="" index="'+i+'" rel=""/>',imgBox);
 65             //window.URL.createObjectURL(file)在opera中返回的竟然是[object file],很蛋疼
 66             if(window.URL && !isOpera){
 67                 img.src = window.URL.createObjectURL(file);
 68                 window.URL.revokeObjectURL(file);
 69             }else if(window.webkitURL){
 70                 img.src = window.webkitURL.createObjectURL(file);
 71                 window.webkitURL.revokeObjectURL(file);
 72             }else{
 73                 (function(img){
 74                     reader = new FileReader();
 75                     reader.readAsDataURL(file);
 76                     reader.onload = function(){
 77                         img.src= this.result;
 78                     };
 79                 })(img);
 80             };
 81             img.addEventListener('dragstart',function(e){e.preventDefault();e.stopPropagation();},false)
 82             editRemark.addEventListener('blur',handleBlur,false);
 83         });
 84         return fragment;
 85     };
 86     function handleControl(e){
 87         var target = e.target,editRemarks = $('sbi_content').querySelectorAll('.editRemark');
 88         if(target.classList.contains('editRemark')) return;
 89         each(editRemarks,function(){
 90             if(this.classList.contains('show')) this.classList.remove('show');
 91         });
 92         target.classList.contains('edit') && handleEdit(target);
 93         target.classList.contains('del') && handleDel(target);
 94     };
 95     function handleEdit(obj){
 96         var parent = closet(obj,'li'),related = parent.querySelectorAll('.editRemark')[0];
 97         parent.classList.add('show');
 98         related.classList.add('show');
 99     };
100     function handleDel(obj){
101         var parent = closet(obj,'li'),dels = closet(obj,'.imgList').querySelectorAll('.del');
102         oFiles.splice(getIndex(dels,obj),1);
103         parent.parentNode.removeChild(parent);
104     };
105     function handleBlur(){
106         var parent = closet(this,'li'),remark = parent.querySelectorAll('.remark')[0],img = parent.querySelectorAll('.img_preview img')[0],v = this.value;
107         parent.classList.remove('show');
108         this.classList.remove('show');
109         remark.classList[v !== '' ? 'add' : 'remove']('hasContent');
110         remark.innerHTML = v.length > 20 ? (v.substr(0,20)+'...') : v;
111         img.setAttribute('rel',v);
112     };
113     function handleCancel(e){
114         e.stopPropagation();
115         handleClose(e);
116     };
117     function handleClose(e){
118         e.stopPropagation();
119         db.removeChild($('sbi_overlayer'));
120         db.removeChild($('sbi_contentOuter'));
121         handleFiles.box = '';
122         handleFiles.ul = '';
123         oFiles = [];
124     };
125     function handleUpload(set){
126         return function(){
127             var imgs = $('sbi_content').querySelectorAll('.img_preview img');
128             var pros = $('sbi_content').querySelectorAll('.progress');
129             var len = imgs.length,i=0;
130             each(imgs,function(i){
131                 var formdata = new FormData();
132                 formdata.append('file[]',oFiles[i]);
133                 formdata.append('remark[]',imgs[i].getAttribute('rel'));
134                 ajax({
135                     url:set.url,
136                     data:formdata,
137                     progress:function(percent){
138                         if(set.progress){
139                             set.progress(percent);
140                             return;
141                         };
142                         pros[i].parentNode.classList.add('show');
143                         pros[i].style.width = percent + '%';
144                     },
145                     success:function(xhr){
146                         if(i==len-1){
147                             set.callback && set.callback();
148                             return;
149                         };
150                         set.success(xhr);
151                         i++;
152                     },
153                     errorfn:function(){
154                         if(set.errorfn){
155                             set.errofn(xhr);
156                             return;
157                         };
158                         i++;
159                     }
160                 });
161             });
162         };
163     };
164     function createWindow(set){
165         var w = Math.max(db.scrollWidth,doc.documentElement.clientWidth),h=Math.max(db.scrollHeight,doc.documentElement.clientHeight);
166         var overlayer = createEl('<div id="sbi_overlayer" style="width:100%;height:100%;position:fixed;top:0;left:0;background:#000;opacity:.8"></div>',db);
167         var contentOuter = createEl('<div id="sbi_contentOuter" style="width:'+set.boxWidth+'px;height='+set.boxHeight+'px;position:fixed;top:50%;left:50%;margin:-'+set.boxHeight/2+'px 0 0 -'+set.boxWidth/2+'px"></div>',db);
168         var close = createEl('<a id="close" href="javascript:void(0)" style="float:right">CLOSE</a>',contentOuter);
169         var content = createEl('<div id="sbi_content" style="clear:both;max-height:'+set.boxHeight+'px;overflow-y:auto"></div>',contentOuter);
170         var btnBox = createEl('<div id="sbi_btnBox"></div>',contentOuter);
171         var btnUpload = createEl('<input id="sbi_upload" type="button" name="sbi_upload" value="上传" />',btnBox);
172         var btnCancel = createEl('<input id="sbi_cancel" type="button" name="sbi_cancel" value="取消" />',btnBox);
173         return {
174            overlayer:overlayer,
175            contentOuter:contentOuter,
176            close:close,
177            content:content,
178            btnBox:btnBox,
179            btnUpload:btnUpload,
180            btnCancel:btnCancel 
181         };
182     };
183     function ajax(opts){return new ajax.prototype.init(opts);};
184     ajax.prototype = {
185         constructor:ajax,
186         init:function(opts){
187             var xhr = new XMLHttpRequest();
188             var set = extend({
189                 url:'',
190                 data:'',
191                 progress:function(){},
192                 success:function(){},
193                 errorfn:function(){}
194             },opts||{});
195             xhr.open('post',set.url,true);
196             xhr.onprogress = xhr.upload.onprogress = function(e){
197                 set.progress(e.loaded*100 / e.total);
198             };
199             xhr.onload = function(){
200                set.success(xhr); 
201             };
202             xhr.onerror = function(){
203                 set.errorfn(xhr);
204             };
205             xhr.send(set.data);
206         }
207     };
208     ajax.prototype.init.prototype = ajax.prototype;
209     
210     /*****************************************************************************/
211    function $(id){
212        return typeof id == 'string' ? doc.getElementById(id) : id;
213    };
214    function extend(target,source){
215        for(var key in source) target[key] = source[key];
216        return target;
217    };
218    function createEl(str,parent){
219        var div = doc.createElement('div'),el;
220        div.innerHTML = str;
221        el = div.firstChild;
222        parent && parent.appendChild(el);
223        return el;
224    };
225    function each(arr,fn){
226        var i=0,len=arr.length;
227        for(;i<len;i++){
228            fn.call(arr[i],i,arr);
229        }
230    };
231    function getIndex(arr,item){
232       for(var i=0,len=arr.length;i<len;i++){
233           if(arr[i] == item){
234               return i;
235           };
236       };
237       return -1;
238    };
239    function merge(target,source){
240        for(var i=0,len=source.length;i<len;i++) target.push(source[i]);
241        return target;
242    };
243    function closet(obj,match){
244        var flag = true;
245        do{
246            obj = obj.parentNode;
247            (/^\.[-\w]+$/.test(match) && obj.classList.contains(match)) && (flag = false);
248            (/^[-\w]+$/.test(match) && obj.nodeName.toLowerCase() == match ) && (flag = false);
249        }while(obj.nodeName && obj != db && flag);
250        return obj
251    };
252 })(window);

CSS:

 1 @charset "utf-8";
 2 /* CSS Document */
 3 @font-face {font-family: 'IcoMoon';src: url('IcoMoon.eot');src: url('IcoMoon.eot?#iefix') format('embedded-opentype'),url('IcoMoon.svg#IcoMoon') format('svg'),url('IcoMoon.woff') format('woff'),url('IcoMoon.ttf') format('truetype');font-weight: normal;font-style: normal;}
 4 html,body {height:100%;}
 5 body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td { margin:0; padding:0; }
 6 body, button, input, select, textarea { font: 12px/1.5 "微软雅黑", "宋体", Arial; }
 7 button, input, select, textarea,img {vertical-align: middle;}
 8 ul{ list-style:none;}
 9 em { font-style: normal;}
10 a{ color:#fff; text-decoration: none;}
11 a:hover{color:#fff; text-decoration: none;}
12 
13 .sbi_item{ display:inline-block; width:220px; height:138px; margin:10px 0 0 10px; position:relative;}
14 .sbi_item:hover .remark{opacity:.8;color:#666;-webkit-transition: all 0.3s ease-in-out;}
15 .sbi_item:hover .control{opacity:.8;-webkit-transition: all 0.3s ease-in-out;}
16 .remark {position: absolute;top:0;left:0;width: 100%;background: #000; opacity: 0;color:#333;z-index: 10;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box; text-align:left;}
17 .hasContent {padding:8px;}
18 .control {position: absolute;bottom:0;left:0;width:100%; background: #000; opacity: 0;color:#fff;height:25px; line-height:25px; text-align:right;z-index: 10;}
19 .control a{padding-right:10px; color:#666;}
20 .control a .icon {color:#666;}
21 .control a:hover, .control a:hover .icon {color:#fff;}
22 .progressbox {width:100%;height:5px;position: absolute; bottom:-5px; background: #333;z-index: 10; display:none; opacity: .8;}
23 .progressbox.show{display:block;}
24 .progress { background: blue;display:block;height:5px;}
25 .editRemark {position: absolute;bottom:-55px;left:0;width:99%;height:50px; display:none;z-index: 10;}
26 .editRemark.show{ display:block;}
27 .img_preview {display:table-cell; vertical-align: middle;width:220px;height:138px;overflow:hidden;}
28 .img_preview img {/* position:relative;top:50%;left:50%;*/display:block; margin:0 auto; max-width:220px;max-height:138px;z-index:0;}
29 .icon { font-family: 'IcoMoon';  font-size:18px;display:inline-block;zoom:1;letter-spacing:0px;line-height:18px; margin-right:5px;text-align:center;vertical-align:-3px;color:#fff;}
30 .del:before {font-family: 'IcoMoon';  font-size:18px; content:'G';font-size:18px; line-height:18px;padding-right:5px;vertical-align:-3px;}
31 .edit:before{font-family: 'IcoMoon';  font-size:18px; content:'D';font-size:18px; line-height:18px;padding-right:5px;vertical-align:-3px;}
32 #close:before {font-family: 'IcoMoon';  font-size:18px; content:'4';font-size:18px; line-height:18px;padding-right:5px;vertical-align:-3px;}
33 #sbi_btnBox { text-align:center; padding-top:10px;}
34 input[type="button"] {background: #333; border-radius:5px; padding:3px 30px; display: inline-block; margin:10px 5px 0; clear:both; color:#fff;}

 

PHP就自己去写吧,接收的数据就是图片(name=file)以及图片的说明文字(name=remark),用firebug看下提交的数据就知道了。

posted @ 2012-08-14 11:41  zjhsd2007  阅读(997)  评论(0编辑  收藏  举报