原生JS實現表單序列化serialize()

邵天宇Soy發表於2019-04-30

使用原生的js模擬了表單序列化,程式碼中對錶單處理儘可能地進行文字說明 其中對於url,欄位名稱,中文進行了使用了encodeURIComponent()進行編碼。

之前部落格有介紹encodeURI和encodeURIComponent的區別

Object.prototype.serialize = function(){
	var res = [],	//存放結果的陣列
		current = null,	//當前迴圈內的表單控制元件
		i,	//表單NodeList的索引
		len, //表單NodeList的長度
		k,	//select遍歷索引
		optionLen,	//select遍歷索引
		option, //select迴圈體內option
		optionValue,	//select的value
		form = this;	//用form變數拿到當前的表單,易於辨識
	
	for(i=0, len=form.elements.length; i<len; i++){
		
		current = form.elements[i];
		
		//disabled表示欄位禁用,需要區分與readonly的區別
		if(current.disabled) continue;
		
		switch(current.type){
			
			//可忽略控制元件處理
			case "file":	//檔案輸入型別
			case "submit":	//提交按鈕
			case "button":	//一般按鈕
			case "image":	//影像形式的提交按鈕
			case "reset":	//重置按鈕
			case undefined:	//未定義
				break;
			
			//select控制元件
			case "select-one":
			case "select-multiple":
				if(current.name && current.name.length){
					console.log(current)
					for(k=0, optionLen=current.options.length; k<optionLen; k++){

						option = current.options[k];
						optionValue = "";
						if(option.selected){
							if(option.hasAttribute){
								optionValue = option.hasAttribute('value') ? option.value : option.text
							}else{
								//低版本IE需要使用特性 的specified屬性,檢測是否已規定某個屬性
								optionValue = option.attributes('value').specified ? option.value : option.text;	
							}
							res.push(encodeURIComponent(current.name) + "=" + encodeURIComponent(optionValue));
						}
					}
				}
				break;
				
			//單選,核取方塊
			case "radio":
			case "checkbox":
				//這裡有個取巧 的寫法,這裡的判斷是跟下面的default相互對應。
				//如果放在其他地方,則需要額外的判斷取值
				if(!current.checked) break;
			
			default:
				//一般表單控制元件處理
				if(current.name && current.name.length){
					res.push(encodeURIComponent(current.name) + "=" + encodeURIComponent(current.value));
				}
			
		}
	}
	
	
	return res.join("&");
}
複製程式碼

對HTML表單使用:

formElement.serialize();
複製程式碼

得到類似如下結果:a=1&b=2&c=3&d=4&e=5

相關文章