因爲討厭各類上傳插件和UI綁定,一樣是爲了本身練練手,我寫了一個十分小巧的jQuery上傳插件——JFilehtml
var jq=$('#input').upload(url,{ preview:true, limits:{ fieldSize:40, ... }, ... }).done(function(data,status,xhr){..}) .fail(function(xhr,status,err){..}) .always(function(xhr,status,err){..}) .progress(function(percentage){..}); jq.abort();
/** * Created by suemi on 14-12-8. */ (function($){ $.fn.upload=function(url,settings){ var option={ method:'POST', action:url, dataType:'json', limits:{}, preview:null }; if(!settings) var settings={}; $.extend(option,settings); var getXhr = function(){ var xhr; return function(){ if (xhr) return xhr; if (typeof XMLHttpRequest !== 'undefined') { xhr = new XMLHttpRequest(); } else { var v = [ "Microsoft.XmlHttp", "MSXML2.XmlHttp.5.0", "MSXML2.XmlHttp.4.0", "MSXML2.XmlHttp.3.0", "MSXML2.XmlHttp.2.0" ]; for (var i=0; i < v.length; i++){ try { xhr = new ActiveXObject(v[i]); break; } catch (e){} } } return xhr; } }(); function checkExtension(dst,src){ var tmp=dst.split('/'); if(tmp[0]=='image'){ if($.inArray('image/*',src)==-1){ if($.inArray(tmp[1],src)==-1) return false; else return true; } else return true; } else{ if($.inArray(tmp[1],src)==-1) return false; else return true; } } var fileList=[]; $(this).each(function(){ for(var i=0;i<this.files.length;i++){ fileList.push(this.files[i]); } }); return $.Deferred(function(){ var xhr=getXhr(); var defer=this; this.abort=function(){ if(xhr) xhr.abort(); return defer; }; this.preview=function(tmp){ for(var i in fileList){ var file=fileList[i]; if(file.type.split('/')[0]=='image'){ if(!window.FileReader){ alert('Too old browser, you need a modern one!'); return defer; } var reader=new FileReader(); reader.name=file.name; reader.onloadend=function(evt){ console.log(this.num); if(reader.error) tmp.append($('<p>'+this.name+' fails to be loaded</p>')); else tmp.append($('<img>',{'src':evt.target.result,'alt':this.name})); }; reader.readAsDataURL(file); } else continue; } return defer; }; if(window.FormData) var form=new FormData(); else{ // alert('Too old for your browser, get a modern one!'); this.reject(xhr,null,new Error('Too Old Browser')); return this; } if(!xhr){ this.reject(xhr,null,new Error('Too Old Browser')); return this; } if(!option.action){ this.reject(xhr,null,new Error('URL Needed')); return this; } xhr.open(option.method,option.action); xhr.upload.addEventListener('progress',function(evt){ if(evt.lengthComputable){ var complete=evt.loaded/evt.total | 0; } defer.notify(complete); }); xhr.onreadystatechange=function(){ if(this.readyState!==4) return; if(this.status==200){ var data; switch(option.dataType){ case 'text': data=this.responseText; break; case 'html': data= $.parseHTML(this.responseText); break; case 'xml': data= $.parseXML(this.responseXML); break; case 'json': data= $.parseJSON(this.responseText); break; default :break; } defer.resolve(data,this.status,this); } else{ defer.reject(this,this.status,this.responseText); } }; if(fileList.length==0){ //defer.reject(xhr,xhr.status,new Error('No File Select')); return defer; } if(option.limits.fieldSize&&option.limits.fieldSize<fileList.length){ var err=new Error('Too Many Files'); defer.reject(xhr,xhr.status,err); return defer; } for(var i in fileList){ var file=fileList[i]; if(option.limits.validExtension&&!checkExtension(file.type,option.limits.validExtension)){ var err=new Error('File Type Error'); err.filename=file.name; defer.reject(xhr,xhr.status,err); continue; } if(option.limits.fileSize&&option.limits.fileSize<file.size){ var err=new Error('Too Large Size'); defer.reject(xhr,xhr.status,err); return defer; } if(option.start) option.start(file); form.append(i,file,file.name); if(option.maxSize) option.maxSize-=file.size; } if(option.preview) this.preview(option.preview); xhr.send(form); return defer; }); }; })(jQuery);