實現一個上傳文件(彈出上傳框)的方法

這裏將要實現一個,通過調用一個方法,彈出來一個上傳文件框。

但如果僅僅只是彈出一個窗口,那就太沒意義了。所以這個可通過一個對象參數,指定與哪個服務交互,文件是否可多選等。

定義該方法名稱爲createFormAndUpload,下面爲調用該方法的例子

createFormAndUpload.call(window,{
	method: 'put',   //請求接口的方法
	multiple: false,  //表單可否多選
	url: '/api/xxxxxx', //請求接口的url
	on: {
		submit: function(files,handle){
		  //選擇文件之後 ,提供一個入口讓使用者可以控制發送請求的時刻
		},
		finishedSubmit: function(files){}, //完成請求後
		error: function(){},//出錯的回調
	}
})

關於參數的屬性method、multiple、url都比較好理解,看註釋即可。
這裏着重說明on屬性對象:

  1. submit
    如果on對象使用該屬性,發送請求的控制權完全交付給使用者,使用者必須調用handle方法才能發送請求
    爲什麼要這麼做呢?在發送請求之前,或許你需要檢查一下文件類型是否符合你的需求,然後再決定是否真的要發送請求
  2. finishedSubmit
    這個屬性是請求完成後,服務返回響應後的回調,使用者可以在這時候根據需要做處理
  3. error
    該屬性是請求完成後,服務返回錯誤的響應碼,或者請求服務失敗,使用的回調

那麼下面就是實現方法的代碼了:

function createFormAndUpload(ops){
	var self = this;	
	var constantForm = 'createFormAndUpload_form',
	 constantInput = 'createFormAndUpload_input';
	var fns = ops.on || {};	
	if(!Object.prototype.hasOwnProperty.call(self,constantForm)){	
		var form = document.createElement('form');
		form.setAttribute('enctype','multipart/form-data')
		form.style.display = 'none'
		var _input = document.createElement('input')
		_input.setAttribute('type','file')
		_input.value = ''
		ops.multiple && _input.setAttribute('multiple','multiple')			
		form.appendChild(_input)
		document.body.appendChild(form);
		self[constantForm] = form;
		self[constantInput] = _input;		
		_input.click();
		_input.addEventListener('change',function(e){
		//點開文件選擇框,如果之前_input的value不爲'',點擊'取消'則也觸發change事件,此時長度爲0
			if(_input.files.length == 0) return; 
			if(fns.submit) fns.submit(_input.files,ajaxHandler)
			else ajaxHandler()			
			function ajaxHandler(){
				console.log('change');																
				var files = _input.files;
				var finishedFlag = 0;
				for(var i=0;i<files.length;i++){
					var xhr = new XMLHttpRequest();
					xhr.responseType = "json";
					var formData = new FormData();
					formData.append('upfile',files[i]);
					xhr.open(ops.method,ops.url,true);
					xhr.send(formData);				
					xhr.onload = function(e){
						var data = this.response;
						finishedFlag++;							
						if(data.error_code==200){
							if(finishedFlag == files.length){								
								delete data.error_code;
								fns.finishedSubmit && fns.finishedSubmit(files,data);
								_input.value = '';
							}							
						}else{
							fns.error && fns.error(files)
						}
					}
					xhr.onerror = function(e){
						fns.error && fns.error(files)
					}
					xhr.ontimeout = function(e){
						fns.error && fns.error(files)
					}					
				}				
			}
		})					
	}else{
		self[constantInput].value = '';
		self[constantInput].click();
	}
}

涉及到跨域或者xhr設置的方面,請訪問你真的會使用XMLHttpRequest嗎?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章