最近公司要做一个html5上传的jquery插件,要在下先实现功能,要求显示上传进度,文件信息,断点续传等等。我一看,艾玛!Σ(゚д゚lll),没做过啊。没办法,(# ゚Д゚),只能去查资料了。
作为一名还未毕业的大学僧,本人表示亚历山大。不过还好是做出来了,不敢说代码写得很好,大家将就着看吧。感谢以下文章提供的思考方向:由于传的时候不小心,文件弄错了,现在bug已修复,对不起啊大家
考虑到服务器原因现在停止上传演示页面,抱歉请大家谅解演示地址:暂停资源地址:HTML:
upload html5
CSS:
style.css
/*************reset****************/html{color:#333;-webkit-text-size-adjust:none;height:100%;max-height:100%;overflow: hidden;font-family: 'Microsoft Yahei';}body{height: 100%;max-height:100%;overflow: hidden;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,var,optgroup{font-style:inherit;font-weight:inherit;}del,ins{text-decoration:none;}li{list-style:none;}h1,h2,h3,h4,h5,h6{font-size:100%;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:baseline;}sub{vertical-align:baseline;}legend{color:#000;}input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;}body{font-size:12px;}a{color: #333333;text-decoration: none;}a:hover{text-decoration:underline; color:#c00;}/*font*/*{ font-size: 1.05em; color: #222; font-family: "Microsoft Yahei";}
upload.css
#upload_box{ padding:0em 1em; padding-top:20px; height:100%; background: #74b1d1; position: relative;}#upload_form{ background: #fff; height: 80%; padding: 1.4em 1em; border-radius: 4px; box-shadow: 0 1px 3px rgba(0,0,0,0.7);}#upload_form label{ font-size: 1.5em; font-weight: bolder;}#file{ margin:20px 0; border:1px solid #ccc; border-radius: 5px; padding: 0.5em; font-size: 1.4em; width: 90%;}#submit,#clear{ font-size:1.2em; padding:0.3em 1.2em; border-radius:10px; border:1px solid #d9d9d9; background: -webkit-linear-gradient(#ffffff,#dfdfdf); background: -o-linear-gradient(#ffffff,#dfdfdf); background: -moz-linear-gradient(#ffffff,#dfdfdf); background: linear-gradient(#ffffff,#dfdfdf); box-shadow:0px 1px 3px rgba(0,0,0,0.7); outline: none;}#submit{ margin-right:1.6em;}#submit:hover,#clear:hover{ background: -webkit-linear-gradient(#66ccff,#74b1d1); background: -o-linear-gradient(#66ccff,#74b1d1); background: -moz-linear-gradient(#66ccff,#74b1d1); background: linear-gradient(#66ccff,#74b1d1); cursor: pointer;}.upload_message_show{ margin-top: 20px; display: none;}.upload_file_message{ padding: 1.4em 0em; padding-left: 60%; padding-right: 1.2em; border-radius: 10px; background: -webkit-linear-gradient(#dfdfdf,#cccccc); background: -o-linear-gradient(#dfdfdf,#cccccc); background: -moz-linear-gradient(#dfdfdf,#cccccc); background: linear-gradient(#dfdfdf,#cccccc); font-size: 1.1em; font-weight: bolder; position: relative; min-height: 6.5em;}.upload_file_error{ color:red;}.message_box{ position: absolute; left: 1.2em; top: 1.4em;}.upload_file_preview{ height: 100%; position: relative;}.upload_bar_box{ width: 100%; height: 1em; border-radius:0.5em; position: relative; box-shadow:0px 0px 3px rgba(0,0,0,0.6); line-height: 1em;}.upload_bar{ width:0%; border-radius:0.5em; background:-webkit-linear-gradient(#F01731,#F50B43); background:-o-linear-gradient(#F01731,#F50B43); background:-moz-linear-gradient(#F01731,#F50B43); background:linear-gradient(#F01731,#F50B43); height:100%;}.upload_percent{ position: absolute; right: 10px; top:0em; font-weight:700;}.upload_count{ width: 100%; font-size:0.8em; margin-top:1em; position: relative;}.left_time{ margin-left: 1em;}.speed{ position: absolute; right:1em; top: 0em;}
js:
变量定义:
var nSlice_count = 100,//分段数,文件分段数 nFactCount, //实际分段数 nMin_size = 0.5,//最小分段大小(M) nMax_size = 5, //最大分段大小(M) nFactSize, //实际分段大小 nCountNum = 0, //分段标号 sFile_type, //文件类型 nFile_load_size, //文件上传部分大小 nFile_size, //文件大小 nPreuploaded = 0, //上一次记录上传部分的大小 bIs_uploading= false,//是否上传中 bStart_upload= false,//是否开始上传 bEnd_upload = false;//是否上传完成
当文件域变化或者点击清空时,重置所有已记录信息:
function messageChange(){ document.querySelector(".upload_file_name").innerHTML ="文件名称: " ; document.querySelector(".upload_file_type").innerHTML ="文件类型: " ; document.querySelector(".upload_file_size").innerHTML ="文件大小: " ; document.querySelector(".isCompleted").innerHTML ="上传状态: " ; document.querySelector(".upload_bar").style.width = "0%"; document.querySelector(".upload_percent").innerHTML = "0%"; document.querySelector(".upload_file_preview").innerHTML =""; document.querySelector(".upload_message_show").style.display = "none";}function clearUploadFile(e){ var e = e || event; e.stopPropagation(); e.preventDefault(); document.getElementById("file").value = ""; bStart_upload = false; messageChange();}function fileReady(){ bIs_uploading = false; bEnd_upload = false; nCountNum = 0; bStart_upload = false; messageChange();}
发生错误时的处理:
function errorUp(){ bStart_upload = false; document.querySelector(".upload_file_error").innerHTML = "上传过程中出错";}function abortUp(){ bStart_upload = false; document.querySelector(".upload_file_error").innerHTML = "网络故障,请检查重试";}
文件上传后提供预览,考虑到手机小屏幕的问题,只在ipad和pc上提供预览,预览的文件类型为
image/video/audio,由于浏览器对多媒体格式的支持不同,不能保证每个文件都能正常播放function filePreview($src){ var ftype = sFile_type; var $temp; var IMGMaxHeight = document.querySelector(".upload_message_show").offsetHeight; switch(ftype){ case "image" : $temp = ''; break; case "audio" : $temp = ' '; break; case "video" : $temp = ' '; break; } var IsPreview = checkUserAgent(); if(IsPreview) document.querySelector(".upload_file_preview").innerHTML = $temp;}function checkUserAgent(){ var msg = true; var agent = ["ipod","iphone","android","symbian","windows mobile"]; var info =navigator.userAgent.toLowerCase(); for(var i=0,j=agent.length;i0) msg = false; } return msg;}
数据单位转化:
var conversion = (function(){ var unitConversion = { bytesTosize:function(data){ var unit = ["Bytes","KB","MB","GB"]; var i = parseInt(Math.log(data)/Math.log(1024)); return (data/Math.pow(1024,i)).toFixed(1) + " " + unit[i]; }, secondsTotime:function(sec){ var h = Math.floor(sec/3600), m = Math.floor((sec-h*3600)/60), s = Math.floor(sec-h*3600-m*60); if(h<10) h = "0" + h; if(m<10) m = "0" + m; if(s<10) s = "0" + s; return h + ":" + m + ":" + s + ":"; } }; return unitConversion; })();
文件上传和上传时的计算:
//start sending var reader = new FileReader(); var timer; var fProgress = function(e){ var fSize = get_file_message.getAll().fileSize; timer = setTimeout(uploadCount(e,fSize,conversion),300); }; var floadend = function(e){ if(reader.error){alert("上传失败,出现未知错误");clearTimeout(timer);return;} clearTimeout(timer); if(nCountNum+1!=nFactCount) { if(bStart_upload) { nCountNum++; uploadStart(); return; } else { document.querySelector(".speed").innerHTML = "0k/s"; document.querySelector(".left_time").innerHTML = "剩余时间 | 00:00:00"; return; } } bEnd_upload = true; document.querySelector(".layer_box").style.display = "none"; document.querySelector(".speed").innerHTML = "0k/s"; document.querySelector(".left_time").innerHTML = "剩余时间 | 00:00:00"; document.querySelector(".upload_percent").innerHTML = "100.00%"; document.getElementById("submit").value = "上传"; var $res = JSON.parse(e.target.responseText); filePreview($res); if($res.res=="success") bIs_uploading =true; document.querySelector(".isCompleted").innerHTML="上传状态: " + (bIs_uploading?"上传完成":"正在上传.."); }; var uploadStart = function(){ var get_all = get_file_message.getAll(); var start = nCountNum * nFactSize, end = Math.min(start+nFactSize,get_all.fileSize); var fData = new FormData(); fData.append("file",file.slice(start,end)); fData.append("name",file.name); fData.append("size",file.size); fData.append("type",file.type); fData.append("totalCount",nFactCount); fData.append("indexCount",nCountNum); fData.append("trueName",file.name.substring(0,file.name.lastIndexOf("."))); document.querySelector(".layer_box").style.display = "block"; if(!sFile_type) sFile_type = file.type.substring(0,file.type.indexOf("/")); var xhr = new XMLHttpRequest(); xhr.upload.addEventListener("progress",fProgress,false); xhr.addEventListener("load",floadend,false); xhr.addEventListener("error",errorUp,false); xhr.addEventListener("abort",abortUp,false); xhr.open("POST","php/send/"); xhr.send(fData); }; reader.onloadstart = function(){ var get_all = get_file_message.getAll(), fName = get_all.fileName, fType = get_all.fileType, fSize = conversion.bytesTosize(get_all.fileSize); document.querySelector(".upload_message_show").style.display = "block"; document.querySelector(".upload_file_name").innerHTML ="文件名称: " + fName; document.querySelector(".upload_file_type").innerHTML ="文件类型: " + fType; document.querySelector(".upload_file_size").innerHTML ="文件大小: " + fSize; document.querySelector(".isCompleted").innerHTML ="上传状态: " + (bIs_uploading?"完成":"正在上传中.."); nFactSize = get_all.fileSize/nSlice_count; nFactSize = (nFactSize>=nMin_size*1024*1024?nFactSize:nMin_size*1024*1024); nFactSize = (nFactSize<=nMax_size*1024*1024?nFactSize:nMax_size*1024*1024); nFactCount= Math.ceil(get_all.fileSize/nFactSize); uploadStart(); }; reader.readAsBinaryString(file);}function uploadCount(e,fSize,conversion){ var upSize = e.loaded+nCountNum*nFactSize, perc = (upSize*100/fSize).toFixed(2) + "%"; var speed = Math.abs(upSize - nPreuploaded); if(speed==0){clearTimeout("timer");return;} var leftTime = conversion.secondsTotime(Math.round((fSize-upSize)/speed)); speed = conversion.bytesTosize(speed)+"/s"; document.querySelector(".speed").innerHTML = speed; document.querySelector(".left_time").innerHTML = "剩余时间 | " + leftTime; document.querySelector(".upload_percent").innerHTML = perc; document.querySelector(".upload_bar").style.width = perc; nPreuploaded = upSize;}
PHP:
"success","url"=>mb_convert_encoding($truename."-".$fsize."/".$fname,'utf-8','gbk')); echo json_encode($res);}?>
还有一些细节的js这里没给出来,主要就上面的功能,有问题的话欢迎回复,楼主只是个新手,不足之处请大家多多见谅。