文件上傳兼容簡直頭疼,爲此特地封裝了個方法,支持IE低版本(>=7)上傳及現代瀏覽器顯示上傳進度,css
此方法只是個hello world,jser可根據本身的需求增減功能及樣式html
敬上代碼,拋磚引玉android
調用web
var $file = $('input控件'); var config = { fileExtension: 'jpg, png, pdf, psd', //容許上傳de文件格式 fileSize: 100*1024*1024, //容許上傳的最大尺寸 uploadUrl: '***', //上傳地址 deleteUrl: '***', //刪除地址 uploadCb: function(res){ console.log('success') }, deleteCb: function(res){ console.log('delete') } } $file.uploadFile(config)
方法ajax
(function($){ // 全局變量 var $this = '', //上傳控件 $container, //最外層容器 $showFileContainer, //顯示文件容器 $showFileItem //顯示單個文件 var fileId = new Date().getTime(); //時間戳,區分每次上傳 var config = {}; // 配置參數 // 關於上傳進度變量 var ot = 0; //上次調用的時間 var oloaded = 0; //已上傳文件大小 var xhr = ''; $.fn.uploadFile = function(conf){ // 接收配置參數 config = conf; $this = $(this); new initLayout($this) var inputData = []; /** * 上傳文件 * ----------- * input files屬性ie10及如下不支持 * formdata ie10如下不支持 * 根據是否支持files屬性判斷現代瀏覽器 */ $('body').on('change propertychange',$this,function(){ fileId = new Date().getTime(); //更新時間戳 // 區分ie10及如下 if(browserInfo().browser.name == "Internet Explorer" && browserInfo().browser.edition*1 < 11){ // ie低版本瀏覽器 // ie單個文件過濾限制 ie_singleFilefilter() }else{ // 現代瀏覽器 var files = $this[0].files; // files無數據跳出 if(!files.length){ return false } // 單個文件過濾限制 new singleFilefilter(files) return false } // 最後執行 clearFile(); }) // 刪除單個文件 $container.on('click',".f-itemDel",function(ev){ if(!config.deleteUrl){ return false } $.ajax({ type: "POST", url: config.deleteUrl, data: {}, success :function(data){ var $del = $(ev.target); $del.closest('.f-item-info').remove(); // 刪除回調 config.deleteCb(data); clearFile(); }, error: function(data){ } }); }) } // 初始化佈局 function initLayout(){ var inpId = $this.prop('id')?$this.prop('id'): (new Date).valueOf(); var $creatParent = $('<div class="f-container">\ <div class="f-input"></div>\ <div class="f-preview"></div>\ <div class="f-button"><label class="f-label-btn" for="'+inpId+'">add file</label></div>\ <div class="f-showInfo"></div>\ </div>'); $this.after($creatParent); $creatParent.find('.f-label-btn').append($this); $container = $creatParent; $showFileContainer = $container.find(".f-showInfo") } /** * singleFilefilter * 單個文件過濾-限制格式、大小、數量 * ------- * @param singleFile * 接收單個文件 * --------- * @return */ function singleFilefilter(files){ var singleFile = files[0]; //獲取單個文件 var extensions = config.fileExtension.split(','); //容許拓展名 var singleExtension = '' ;// 單文件拓展名 var singleSize = singleFile.size; //單文件大小 var isNext = false; // 格式限制 singleExtension = singleFile.name.substring(singleFile.name.lastIndexOf(".")+1).toLowerCase(); if(extensions && extensions.length){ for(var i = 0; i < extensions.length; i++){ if(singleExtension == extensions[i].trim()){ isNext = true; } } } // 判斷isNext和singleExtension,爲空或爲false時提示 if(!isNext){ alert('文件格式不正確!'); clearFile() return false; } // 大小限制 if(singleSize > config.fileSize){ alert("文件過大!") clearFile() return false; } //顯示正在上傳文件 new showFile(singleFile) // 獲取數據 var uploadDate = new FormData(); uploadDate.append("file",singleFile); // ajax上傳 new ajaxUpload(uploadDate); } // 現代瀏覽器上傳 function ajaxUpload (uploadDate){ $.support.cors = true; ot = new Date().getTime();//獲取上傳開始時間 $.ajax({ type: "POST", url: config.uploadUrl, data: uploadDate,//這裏上傳的數據使用了formData 對象 processData : false, //必須false纔會自動加上正確的Content-Type contentType : false , //這裏咱們先拿到jQuery產生的 XMLHttpRequest對象,爲其增長 progress 事件綁定,而後再返回交給ajax使用 xhr: function(){ xhr = $.ajaxSettings.xhr(); var res = 0; xhr.upload.onprogress=progressFunc; //文件上傳進度 // 如下部分待測試 // xhr.upload.onload = res = uploadComplete; //請求完成 // xhr.upload.onerror = uploadFailed; //請求失敗 // xhr.upload.onabort=abortFunc(); //文件上傳取消 return xhr; }, success :function(data){ if(config.callback){ config.callback(data); } clearFile(); }, error: function(data){ } }); } // 文件上傳進度 function progressFunc(evt){ // evt.total是須要傳輸的總字節,evt.loaded是已經傳輸的字節。若是evt.lengthComputable不爲真,則evt.total等於0 var nt = new Date().getTime();//獲取上傳開始時間 if (evt.lengthComputable) { var num = Math.round(evt.loaded / evt.total * 100); //轉換百分比 if(num == 100){ // 隱藏進度條 // hiddenUploading($progressBar); } num += "%"; $showFileItem.find(".f-itemPmgressBar .f-pmgress").css({ width: num }) // 計算速率oloaded var preTime = (nt-ot)/1000; var preLoad = evt.loaded - oloaded; oloaded = evt.loaded; //從新賦值已上傳文件大小,用如下次計算 var speed = preLoad/preTime; var unit = 'b' // 單位轉換 if(speed/1024 > 1){ speed = speed/1024; unit = 'kb'; } if(speed/1024 > 1){ speed = speed/1024; unit = 'M'; } // 小數只保留兩位 if(parseInt(speed)!=speed){ speed = speed.toFixed(2); } // 顯示速度 $showFileItem.find(".f-itemSpeed").html(speed + unit + "/s" ) // 上傳完刪除進度條及速度 if(evt.total == evt.loaded){ $showFileItem.find(".f-itemPmgressBar").remove(); $showFileItem.find(".f-itemSpeed").remove(); } } } // 顯示文件數據 function showFile(file){ var size = file.size; var unit = 'b'; // 單位轉換 if(size/1024 > 1){ size = size/1024; unit = 'kb'; } if(size/1024 > 1){ size = size/1024; unit = 'M'; } // 小數只保留兩位 if(parseInt(size)!=size){ size = size.toFixed(2); } var itemTemp = '<div class="f-item-info" data-id="'+ fileId +'">\ <span class="f-itemName">'+ file.name +'</span>\ <span class="f-itemSize">('+ size + unit +')</span>\ <span class="f-itemPmgressBar"><span class="f-pmgress"></span></span>\ <span class="f-itemSpeed"></span>\ <span class="f-itemDel">delete</span>\ </div>' $showFileContainer.append(itemTemp); $showFileItem = $showFileContainer.find(".f-item-info[data-id = "+ fileId +"]") } // ie單個文件過濾限制 function ie_singleFilefilter(){ var fPath = $this.val() //文件路徑+文件名 var fName = fPath.substring(fPath.lastIndexOf("\\") + 1); //文件名 var extensions = config.fileExtension.split(','); //容許拓展名 var singleExtension = /\.[a-zA-Z]+$/.exec($this.val())[0].substring(1); // 單文件拓展名 var isNext = false; // 格式限制 if(extensions && extensions.length){ for(var i = 0; i < extensions.length; i++){ if(singleExtension == extensions[i].trim()){ isNext = true; } } } // 判斷isNext和singleExtension,爲空或爲false時提示 if(!isNext){ alert('文件格式不正確!'); clearFile(); return false; } var opt={ iName: $this.prop('id')+' ', url: config.url, callback: config.callback, file: { name: fName } } // 動態建立iframe上傳文件 creatIframe(opt) } // 建立iframe及表單提交 function creatIframe(opt){ var $f_parent = $this.parent(); var $iframe = $('<iframe name="'+ opt.iName +'" id="' + opt.iName + '" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"/>'); var $form = $('<form method="post" style="display: none;" target="'+opt.iName+'" action="'+opt.url+'" name="form_'+opt.iName+'" enctype="multipart/form-data" />'); // 將控件插入form表單 $("body").append($iframe); // var $form = $('body').find('form'); $("body").append($form); $form.append("<input name='test' type='text'>").append($this); // $form.append($("#uploadFile")); // 表單提交 $form.submit(); // 獲取數據,刪除iframe $iframe.ready(function(){ var data = $iframe.contents().find('body').html(); if(opt.callback){ opt.callback(data); } // 刪除iframe,form $iframe.remove(); $form.remove(); // 控件放回原始位置 $f_parent.append($this); ie_showFileinfo(opt); clearFile(); return false }) } // ie文件顯示 function ie_showFileinfo(opt){ var itemTemp = '<div class="f-item-info" data-id="'+ fileId +'">\ <span class="f-itemName">'+ opt.file.name +'</span>\ <span class="f-itemDel">delete</span>\ </div>' $showFileContainer.append(itemTemp); $showFileItem = $showFileContainer.find(".f-item-info[data-id = "+ fileId +"]") } //取消上傳 // abortFunc(); function abortFunc(){ // 關閉xhr xhr.abort(); console.log("上傳取消"); } // 清空文件 function clearFile(){ if(browserInfo().browser.name == "Internet Explorer" && browserInfo().browser.edition*1 < 11){ document.getElementById($this.prop("id")).outerHTML += ''; }else{ $this.val(''); } } // 獲取瀏覽器信息 var browserInfo = function() { var NT = { '4.90': 'Windows ME', '4.0': 'Windows NT', '5.0': 'Windows 2000', '5.01': 'Windows 2000 SP1', '5.1': 'Windows XP', '5.2': 'Windows XP 64-bit / Windows Server 2003', '6.0': 'Windows Vista / Windows Server 2008', '6.1': 'Windows 7 / Windows Server 2008 R2', '6.2': 'Windows 8', '6.3': 'Windows 8.1', '6.4': 'Windows 10 Technical Preview', '10.0': 'Windows 10' } var userAgent = navigator.userAgent.toLowerCase(); var platform = navigator.platform; var browserName = /(msie\s|trident.*rv:)([\w.]+)/.test(userAgent) ? 'Internet Explorer': (window.opera && window.opera.version ? 'Opera': ((userAgent.indexOf('edge') > -1) ? 'Microsoft Edge': ((userAgent.indexOf('chrome') > -1) ? 'Chrome': ((userAgent.indexOf("firefox") > -1) ? 'Firefox': (userAgent.indexOf('safari') > -1 ? 'Safari': 'Unknown'))))); var browserVersion = browserName == 'Internet Explorer' ? (userAgent.indexOf('rv:') > -1 ? userAgent.match(/rv:[\d.]+/gi)[0].replace('rv:', '') : userAgent.match(/msie\s[\d.]+/gi)[0].replace('msie ', '')) : (browserName == 'Microsoft Edge' ? userAgent.match(/edge\/[\d.]+/gi)[0].replace('edge/', '') : (browserName == 'Firefox' ? userAgent.match(/firefox\/[\d.]+/gi)[0].replace('firefox/', '') : (browserName == 'Chrome' ? userAgent.match(/chrome\/[\d.]+/gi)[0].replace('chrome/', '') : (browserName == 'Safari' ? userAgent.match(/safari\/[\d.]+/gi)[0].replace('safari/', '') : 'Unknown')))); var browserEdition = browserVersion.split('.')[0]; var kernelName = userAgent.indexOf('trident') > -1 ? 'Trident': userAgent.indexOf('edge') > -1 ? 'Edge': (((userAgent.indexOf('applewebkit') > -1) ? 'Webkit': ((userAgent.indexOf('gecko') > -1) ? 'Gecko': 'Unknown'))); var kernelVersion = kernelName == 'Trident' ? (userAgent.match(/Trident\/[\d.]+/gi)[0].replace('Trident/', '')) : (browserName == 'Firefox' ? userAgent.match(/gecko\/[\d.]+/gi)[0].replace('gecko/', '') : ((browserName == 'Chrome' || browserName == 'Safari') ? userAgent.match(/applewebkit\/[\d.]+/gi)[0].replace('applewebkit/', '') : (browserName == 'Microsoft Edge' ? userAgent.match(/edge\/[\d.]+/gi)[0].replace('edge/', '') : 'Unknown'))); var kernelEdition = kernelVersion.split('.')[0]; var osName = userAgent.indexOf('android') > -1 ? 'Android': (userAgent.indexOf('ipad') > -1 ? 'iOS(iPad)': (userAgent.indexOf('iphone') > -1 ? 'iOS(iPhone)': userAgent.indexOf('windows phone') > -1 ? 'Windows Phone': (((platform == "Win32") || (platform == "Windows") ? 'Microsoft Windows': (navigator.platform == "Mac68K") || ((navigator.platform == "MacPPC") || (navigator.platform == "Macintosh") || (navigator.platform == "MacIntel") ? 'Apple Mac': 'Unknown'))))); var osEdition = osName == 'Android' ? userAgent.match(/android\s[\d.]+/gi)[0].replace('android ', '') : ((osName == 'iOS(iPad)' || osName == 'iOS(iPhone)') ? userAgent.match(/os\s[\d_]+/gi)[0].replace('os ', '').replace('_', '.') : (osName == 'Windows Phone' ? userAgent.match(/windows\sphone\s[\d.]+/gi)[0].replace('windows phone ', '').replace('_', '.') : (osName == 'Microsoft Windows' ? (NT[userAgent.match(/windows\snt\s[\d.]+/gi)[0].replace('windows nt ', '')] ? NT[userAgent.match(/windows\snt\s[\d.]+/gi)[0].replace('windows nt ', '')] : 'Unknown') : 'Unknown'))); return { browser: { name: browserName, edition: browserEdition, version: browserVersion }, kernel: { name: kernelName, edition: kernelEdition, version: kernelVersion }, os: { name: osName, edition: osEdition } }; } })(jQuery)