表單是先後端數據交互的一種重要方式,使用js操做表單也是十分常見的。不過好像每次到表單操做我都要去查API,因此本次想對錶單的經常使用操做作個小結,以備後面隨時查看。html
首先,咱們要知道以下的一些知識:ios
1. 表單字段在向後臺提交數據時,使用的是表單控件的name屬性的value,與id無關。(你們能夠在百度搜細說表單找到Fish Li大神的這篇文章看看)ajax
2. 表單向服務端傳數據時會通過編碼。目前基本上只會只使用二種編碼規則:application/x-www-form-urlencoded 和 multipart/form-data , 這二個規則的使用場景簡單地說就是:後者在上傳文件時使用,其它情形則使用前者(默認)。當使用ajax的post方式向後端傳數據時,也會經常設置其header頭來模擬表單的數據提交方式:xhr.setRequestHeader(‘cotent-type’, ‘application/x-www-form-urlencoded ’);這樣後端程序就能夠像處理表單數據那種處理傳過來的參數了後端
3. 表單字段共有的屬性包括:數組
① disbled: 布爾值,表示當前字段是否禁用服務器
② readOnly: 布爾值,表示當前字段是不是隻讀的app
③ type: 當前字段類型,對input元素來講,type屬性就等於其html中寫定的type屬性,如text, password, checkbox, radio, submit, textarea..post
但要注意select元素的type,對於單選的select元素,其type爲select-one, 多遠的select元素,type爲select-multiplethis
④ name:當前字段的名稱,也是做爲有效控件默認向服務器傳送數據時的key編碼
⑤ value: 對多遠的select元素的value,select.value只能取到第一個選中option的value; 要獲取checkbox和radio的value只有經過遍歷。除此以外,其它元素的value便是將發向服務器的value,能夠經過element.value直接獲得
⑥ tabIndex: 當前字段的tab切換序號
⑦ form: 字段所屬的表單
除了form屬性不能寫以外,其它共有屬性都是可讀寫的
4 . 表單字段共的有方法有:focus(), blur()
5. 表單字段共有的事件有:focus, blur, change
6. select元素的額外方法:
除了表單字段共有的屬性和方法外,select元素還有下列屬性和方法:
① add(newOption, relOption), 向select元素中插入新的option, 新插入的option的位置在relOption以前
② opitions: 獲得全部的option的HTMLCollection
③ remove(index): 移除指定位置的option
④ selectIndex: 獲取選中項的索引(從0開始),若沒有選中項,返回-1,對於支持多選項的select,返回第一個選中的項
⑤ size: 選擇框中可見的行數,等價於HTML中的size屬性
⑥ select的type屬性爲select-one/select-multiple
⑦ 若是沒有選中項,select的value爲空字符串 (「」);若是有一個選中項,且其option的value已經指定,則select的value爲選中的option的value, 即便選中的option的value的值爲空串;若選中的option的value值沒有指定,則select的value爲此option的文本;如有多個選中項,select的value以第一個選中的項爲準
對於option元素,爲了方便訪問數據,HTMLOptionElement包含了如下屬性:
① index: 此選項在options集合中的索引
② label:此選項的標籤,等價於HTML中的label特性
③ selected:此選項是否被選中
④ text: 此選項的文本
⑤ value:此選項的值,等價於HTML中的value
select操做封裝:
select: { //select操做 addItem: function(select, value, text, pos) { var option = document.createElement('option'); option.setAttribute('value', value); option.innerHTML = text; if(pos) { select.insertBefore(option, select.querySelectorAll('option')[pos]); } //注意這裏傳了一個undefined參數, select.add(option, undefined); return option; }, removeItem: function(select, index) { //可使用select.options訪問全部的options元素 select.removeChild(select.options[index]); //select.remove(index) 這樣也能夠 }, selectItemByIndex: function(select, index) { var options = select.options; options[index].selected = true; }, selectItemByVal: function(select, val) { var options = select.options, index; for(var i = 0, l = options.length; i < l; i++) { if(options[i].value === val) { index = i; break; } } this.selectItemByIndex(select, index); }, val: function(select, value) { if(value) { this.selectItemByVal(select, value); } else { return select.value; } }, getSelectedIndex: function(select) { //獲取當前選中項的索引, 若是對象有設置mutiple屬性,則返回一個索引數組 var ret = [], i = 0, options, temp; if(! select.multiple) { return select.selectedIndex; } options = select.options; while(temp = options[i]) { if(temp.selected) ret.push(i) i++; } return ret; } }
checkbox封裝:
checkbox: { all: function(checkboxs, flag) { //全選, 全不選, flag === true,全選中, flag === false,全不選 var checkbox, i = 0; while(checkbox = checkboxs[i]) { checkbox.checked = flag; i++; } }, inverse: function(checkboxs) { //反選 var checkbox, i = 0; while(checkbox = checkboxs[i]) { checkbox.checked = !checkbox.checked; i++; } }, selectItemByVal: function(checkboxs, val) { var index; for(var i = 0, l = checkboxs.length; i < l; i++) { if(checkboxs[i].value === val) { checkboxs[i].checked = true; break; } } } }
radio封裝
radio: { selectItemByIndex: function(radios, index) { if(radios[index]) { radios[index].checked = true; } }, selectItemByVal: function(radios, val) { var index; for(var i = 0, l = radios.length; i < l; i++) { if(radios[i].value === val) { radios[i].checked = true; break; } } } }
取得有效表單控件的name和value,組成一個dataMap
dataMap: function(form) { //取得把有效的表單控件的name和值,組成一個數據map var nameMap = {}, dataMap = {}, name, _slice = [].slice; //查找表單中有效的表單控件: /** * 什麼是有效表單控件(參考Fish Li博客-細說表單): 1. 控件不能是【禁用】狀態,即指定【disabled="disabled"】。即:禁用的控件將不是成功控件。 2. 若是一個表單包含了多個提交按鍵,那麼僅當用戶點擊的那個提交按鈕纔算是成功控件。 3. 對於checkbox控件來講,只有被用戶勾選的纔算是成功控件。 4. 對於radio button來講,只有被用戶勾選的纔算是成功控件。 5. 對於select控件來講,全部被選擇的選項都作爲成功控件,name由select控件提供。 6. 對於file上傳文件控件來講,若是它包含了選擇的文件,那麼它將是一個成功控件。 */ //收集input元素的name _slice.call(form.querySelectorAll('input')).forEach(function(e, i) { var name = e.name; if(! nameMap[name]) nameMap[name] = name; }); //收集select元素的name _slice.call(form.querySelectorAll('select')).forEach(function(e, i) { var name = e.name; if(! nameMap[name]) nameMap[name] = name; }); //收集textarea _slice.call(form.querySelectorAll('textarea')).forEach(function(e, i) { var name = e.name; if(! nameMap[name]) nameMap[name] = name; }); //遍歷nameMap,並取得相應的表單控件的值,組成dataMap for(name in nameMap) { if(nameMap.hasOwnProperty(name)) { _slice.call(document.getElementsByName(name)).forEach(function(e, i) { if(e.type === 'checkbox'|| e.type === 'radio') { //可能多遠 dataMap[name] = dataMap[name] || []; if(e.checked) { dataMap[name].push(e.value); } } else if(e.type === 'select-multiple') { //注意能夠多選的select的type屬性爲 select-multiple //可能多選 dataMap[name] = dataMap[name] || []; _slice.call(e.options).forEach(function(e, i) { if(e.selected) { dataMap[name].push(e.value); } }); } else { dataMap[name] = e.value; } }) } } return dataMap; }
練習時的源代碼:下載地址