Javascript中的Form表單知識點總結

本人做php的,最近發現JS真的是博大精深啊,比PHP難.
在HTML中,表單是由form元素來表示的,但是在javascript中,表單則由HTMLFormElement類型,此元素繼承了HTMLElement,因此與其他HTML元素具有相同的默認屬性;HTMLFormElement有自己以下屬性和方法;

acceptCharset: 服務器能夠處理的字符集;等價于HTML中的accept-charset特性;
**action: **接收請求的URL,等價于HTML中的action
**elements: **表單中所有控件的集合.
enctype: 請求的編碼類型;等價于HTML中的enctype特性;
**length: **表單中控件的數量;
method: 要發送的http請求類型,一般是get或者是post,等價于HTML中的method;
**name: **表單的名稱;
**reset(): **將所有表單域重置為默認值;
submit(): 提交表單;
target:用于發送請求和接收響應的窗口名稱;
如何獲取form表單的引用?
假如現在頁面上有一個form表單元素,html代碼如下:

<form id="form" name="form1"></form>```
我現在想取到上面的form表單的引用,一共有以下方式可以獲取到上面 的form表單引用;
1. 通過獲取form表單的id,來獲取form表單的引用;如下代碼:

var formId = document.getElementById("form");
console.log(formId);```

  1. 通過document.forms 取得頁面中的所有表單元素,然后通過索引來取到對應的form元素,如下代碼所示:取得頁面第一個form元素;
console.log(document.forms[0]);```
3. 通過from表單中的name屬性來獲取,代碼如下:

console.log(document.forms['form1']);```

如何提交表單
下面的所有事件都是來自上一篇博客javascript事件總結的事件,都依賴于此封裝的事件,代碼如下:

var EventUtil = { 
  addHandler:function(element,type,handler) {
      if(element.addEventListener) { 
        element.addEventListener(type,handler,false);     
      }else if(element.attachEvent) {
        element.attachEvent("on"+type,handler); 
      }else { 
        element["on" +type] = handler; 
      }
   }, 
  removeHandler: function(element,type,handler){   
      if(element.removeEventListener) {
        element.removeEventListener(type,handler,false); 
      }else if(element.detachEvent) {  
        element.detachEvent("on"+type,handler); 
      }else { 
        element["on" +type] = null; 
      } 
    }, 
  getEvent: function(event) { 
      return event ? event : window.event; 
   }, 
  getTarget: function(event) { 
      return event.target || event.srcElement; 
   }, 
  preventDefault: function(event){ 
      if(event.preventDefault) { 
        vent.preventDefault(); 
      }else{ 
        event.returnValue = false; 
      } 
    }, 
   stopPropagation: function(event) { 
      if(event.stopPropagation) { 
        event.stopPropagation(); 
      }else { 
        event.cancelBubble = true; 
      }  
    }, 
    getRelatedTarget: function(event){ 
      if (event.relatedTarget){ 
        return event.relatedTarget; 
      } else if (event.toElement){ 
        return event.toElement; 
      } else if (event.fromElement){ 
        return event.fromElement; 
      } else { 
        return null; 
      }
    }, 
    getWheelDelta: function(event) { 
      if(event.wheelDelta) {
        return event.wheelDelta; 
      }else { 
        return -event.detail * 40 
      }
    }, 
    getCharCode: function(event) { 
      if(typeof event.charCode == 'number') { 
        return event.charCode; 
      }else { 
        return event.keyCode; 
      } 
    }
};```
用戶單擊提交按鈕或圖像按鈕時,就會提交表單,使用input或者button都可以提交表單,只需將type設置為submit或者image即可,如下三種方式都可以;
第一種:

<form id="form" name="form1" action="http://www.baidu.com">

<input type="text">
<input type="submit" value="submit">
</form>```
第二種:

<form id="form" name="form1" action="http://www.baidu.com"> 
<!-- 存放一個input放在這,為了獲取焦點,然后我們可以按enter鍵提交 --> 
<input type="text">
<button type="submit">submit</button>
</form>```
第三種:

<form id="form" name="form1" action="http://www.baidu.com">

<input type="text">
<input type="image" src="aa.jpg">
</form>```
我們也可以通過如下方式提交表單,但是也可以阻止form表單提交:如下代碼:

EventUtil.addHandler(
    formId,"submit",function(event){ 
    // 取得事件對象 
    event = EventUtil.getEvent(event);
     // 阻止默認事件 EventUtil.preventDefault(event);
    }
);```
**如何重置表單**
如果我們使用按鈕重置表單的話,有下面2種方式:
第一種代碼如下:

<form id="form" name="form1" action="http://www.baidu.com">
<input type="text">
<input type="reset" value="reset">
</form>

第二種代碼如下:

<form id="form" name="form1" action="http://www.baidu.com">
<input type="text">
<button type="reset">reset</button>
</form>```

我們也可以通過像提交form表單一樣來進行重置表單,代碼如下:

 var formId = document.getElementById("form");
formId.reset();

如何訪問表單字段?
第一種方式我們可以使用dom節點來訪問;
第二種方式:每個表單都有elements屬性,該屬性是表單中所有表單元素的集合;這個elements是個有序列表;包含著所有字段,比如有input,textarea,button,fieldset等;
比如如下HTML代碼:

<form id="form" name="form1" action="http://www.baidu.com"> 
<input type="text" name="input1"> 
<select name="select1"> 
<option>111</option>
</select>
</form>

JS獲取表單字段如下:

var formId = document.getElementById("form");
// 取得表單中的第一個字段
var firstCol = formId.elements[0];
console.log(firstCol);
// 取得名字name為select1的字段
console.log(formId.elements['select1']);
// 取得表單中包含字段的數量
console.log(formId.elements.length);

如果一個表單中,有多個name相同的屬性,那么取得數據是一個集合,如下HTML代碼:

<form id="form" name="form1" action="http://www.baidu.com">
<input type="radio" name="radio2"/> 
<input type="radio" name="radio2"/> 
<input type="radio" name="radio2"/>
</form>```
JS代碼如下:

var formId = document.getElementById("form");
var radios = formId.elements["radio2"];
console.log(radios.length);
// 打印3```
共有的表單字段屬性
所有的表單字段都有一組相同的屬性;表單共有的屬性如下:
disabled: 布爾值,表示當前字段是否被禁用;
form: 指向當前字段所屬表單的指針,只讀;
name: 當前字段的名稱;
readOnly:布爾值,表示當前字段是否可讀。
tabIndex: 表示當前字段的切換(tab)序號。
type: 當前字段的類型,如checkbox,radio等;
value: 當前字段被提交到服務器的值;
共有的表單字段方法
每個表單字段都有兩個方法focus()和blur(),其中focus是獲取焦點;比如在頁面加載完成后,我希望form表單中的第一個字段獲取焦點(除隱藏域之外);如下代碼:

<form id="form" name="form1" action="http://www.baidu.com"> 
<input type="text" name="radio2"/> 
<input type="text" name="radio2"/> 
<input type="text" name="radio2"/>
</form>```
JS代碼如下:

var formId = document.getElementById("form");
EventUtil.addHandler(
window,'load',function(event){
formId.elements[0].focus();
}
);```
但是HTML5中為表單字段新增了一個autofocus屬性,在支持這個屬性瀏覽器中,如果設置了這個屬性,不用javascript就能將焦點移動到某個輸入框下,比如如下HTML代碼,在頁面加載完成后,我把焦點放在第二個輸入框內,如下HTML代碼:

<form id="form" name="form1" action="http://www.baidu.com"> 
<input type="text" name="radio2" /> 
<input type="text" name="radio2" autofocus/>
<input type="text" name="radio2"/>
</form>```
支持**autofocus**屬性的瀏覽器有:firefox4+,safari5+,chrome和Opera9.6+
但是我想要兼容其他不支持autofocus的瀏覽器,我們可以寫一段JS,為了全兼容;

var formId = document.getElementById("form");
EventUtil.addHandler(window,'load',function(event){
var element = formId.elements[1];
if(element.autofocus !== true) {
element.focus();
}
}
);

因為``autofocus``是一個布爾值,支持他的瀏覽器默認為true;不支持他的瀏覽器,默認值為空字符串;
**共有的表單字段事件**
所有的表單字段都支持以下三個事件;
blur:當前字段失去焦點時觸發;
change:對于input和textarea元素,值發生改變的時候觸發;
focus: 當前字段獲得焦點時觸發;
**理解文本框腳本**
在HTML中,有2種方式來實現文本框,一種是input元素的單行文本框,另一種是textarea元素的多行文本框;
input元素有屬性type=”text”, 還可以通過設置size屬性,用來指定文本框顯示的字符數,還可以設置value,用來顯示文本框的初始值,還可以設置maxlength屬性,用于指定文本框可以接受的最大字符數;如下代碼:
``<input type="text" size="2" maxlength='12' value=""/>``
多行文本框textarea也有一些屬性,這里就不做多介紹了;
**如何選擇文本:**
input和select兩種元素都支持select()方法,這個方法用于選擇文本框中的所有文本,在調用select()方法中(除Opera外),都會將焦點設置到文本框中,這個方法不接受任何參數,如下代碼:

<form id="formId">
<input type="text" name="input" value="我是龍恩"/>
</form>```
JS代碼如下:

var formId = document.getElementById("formId");
formId.elements['input'].select();```
如下圖所示:

![](http://upload-images.jianshu.io/upload_images/2229907-9e1305589205ab26.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
如上是頁面一進來的時候,默認選擇input元素框所有的內容;我們也可以當獲取焦點的時候,就選中所有的內容,JS代碼可以改為如下:

var formId = document.getElementById("formId"),
input = formId.elements['input'];
EventUtil.addHandler(input,"focus",
function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
target.select();
}
);```
在火狐和谷歌瀏覽器下能實現當獲取焦點的時候,就選中input元素框內的所有內容,但是在IE7或者8下,還是頁面加載完后就已經選中了文本框內的所有元素;
** 1.選擇事件(select)**
與select方法對應的,還有一個select事件,在IE9+,firefox,chrome,opera和safari中,只有用戶選擇了文本且釋放鼠標時,會觸發select事件;但是在IE8及以下,只要用戶選擇了一個字母且不必釋放鼠標,就會觸發select事件;如下代碼:

var formId = document.getElementById("formId"),
  input = formId.elements['input'];
  EventUtil.addHandler(
    input,"select",
    function(event){ 
        alert(input.value);
      }
  );```
**2. 取的選擇的文本**
雖然通過select事件我們知道用戶什么時候選擇了文本,但是我們并不知道用戶選擇了什么文本,在HTML5中,我們通過兩個屬性selectionStart和selectionEnd,這兩個屬性表示選擇的范圍(即文本區開頭和結尾的偏移量);因此要取得用戶選擇的文本,可以使用如下代碼;

var formId = document.getElementById("formId"),
input = formId.elements['input'];
EventUtil.addHandler(input,"select",
function(event){
alert(getSelectedText(input));
}
);
function getSelectedText(elem) {
return elem.value.substring(
elem.selectionStart,elem.selectionEnd
);
}```
但是目前瀏覽器支持程度有:IE9+,firefox,chrome,Opera及safari;
IE8及之前的版本不支持這兩個屬性,但是他們提供了另外一種document.selection對象,其中保存著用戶在整個文檔范圍內選擇的文本信息,但是呢與前面的select事件使用在一起的話,只能選擇一個字符就會觸發事件,也就是說,不能選擇大于1和字符的文字,不過可以知道選擇的值時多少;如下代碼:

var formId = document.getElementById("formId"),
  input = formId.elements['input'];
    EventUtil.addHandler(input,"select",
      function(event){ 
        alert(getSelectedText(input));
      }
    );
    function getSelectedText(elem) { 
      if(typeof elem.selectionStart == "number") {
        return elem.value.substring(
          elem.selectionStart,elem.selectionEnd
        ); 
      }else if(document.selection) { 
        return document.selection.createRange().text; 
      }
    }```
**選擇部分文本**
HTML5也為選擇文本框中的部分文本提供了解決方案,使用setSelectionRange()方法,這個方法接收2個參數,要選擇的第一個字符的索引,和要選擇的最后一個字符之后的字符的索引;
瀏覽器支持有:IE9+,chrome,safari和opera,**firefox****貌似不支持;**
代碼如下:

var formId = document.getElementById("formId"),
input = formId.elements['input'];
input.value = "我是龍恩,我是中國人";
// 選擇所有文本
input.setSelectionRange(0,input.value.length);```
截圖如下:



// 選擇前3個字符

input.setSelectionRange(0,3);```
截圖如下:
![](http://upload-images.jianshu.io/upload_images/2229907-0a16e967ca7bebc9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

// 選擇第四到第六個字符
``input.setSelectionRange(4,7);``
截圖如下:
![](http://upload-images.jianshu.io/upload_images/2229907-75d9b8e65566e4e6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

IE8及以下版本可以使用范圍來選擇部分文本,要選擇部分文本,必須首先使用IE在所有文本框中提供的``createTextRange()``方法創建一個范圍,且我們需要使用collapse()將范圍折疊到文本框的開始位置,再使用``moveStart()``和``moveEnd()``這兩個范圍方法將范圍移動到位;
如下代碼選擇所有的文本:

input.value = "我是龍恩,我是中國人";
var range = input.createTextRange();
// 選擇所有文本
range.collapse(true);
range.moveStart("character",0);
range.moveEnd("character",input.value.length);
range.select();```
演示如下:


切記:使用F5刷新沒有用的,要在地址欄中,然后按enter鍵刷新即可看到效果;

// 選擇前3個字符
range.collapse(true);
range.moveStart("character",0);
range.moveEnd("character",3);
range.select();```
演示如下:
![](http://upload-images.jianshu.io/upload_images/2229907-e7e5a303b3471421.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
// 選擇第4到第6個字符
```range.collapse(true);
range.moveStart("character",4);
range.moveEnd("character",3);
range.select();```

演示如下:
![](http://upload-images.jianshu.io/upload_images/2229907-365912c2c37f7da1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
為了讓跨瀏覽器效果,我們可以封裝一個方法,如下:

function selectText(elem,startIndex,stopIndex) {
if(elem.setSelectionRange) {
elem.setSelectionRange(startIndex,stopIndex);
}else if(elem.createTextRange) {
var range = elem.createTextRange();
range.collapse(true);
range.moveStart("character",startIndex);
range.moveEnd("character",stopIndex-startIndex);
range.select();
}
}```
測試數據如下:貌似****firefox****不支持

// 選擇所有文本
selectText(input,0,input.value.length); 
// 選擇前3個字符
selectText(input,0,3);
// 選擇第四個字符到第六個字符
selectText(input,4,7);

過濾輸入
** 有時候我們會要求用戶在輸入框里面輸入特定格式的數據,我們就可以使用過濾輸入這種手段來進行了,首先我們來看看如何屏蔽字符;
** 1. 屏蔽字符

比如我在一個input輸入框中,只允許只能輸入數字,那么我們可以先獲取通過keypress事件來監聽,然后每次獲取到鍵碼,然后通過String.fromCharCode()這個方法,把鍵碼轉換成字符串,然后通過正則判斷下,如果不是數字,直接阻止默認事件即可不讓用戶輸入,如下代碼:

<form id="formId"> 
  <input type="text" name="input"/>
</form>```
JS代碼如下:

var formId = document.getElementById("formId"),
input = formId.elements['input'];
EventUtil.addHandler(input,'keypress',
function(event) {
event = EventUtil.getEvent(event);
var charCode = EventUtil.getCharCode(event);
if(!/\d/.test(String.fromCharCode(charCode))) {
EventUtil.preventDefault(event);
}
}
); ```
如上代碼能滿足日常需求,但是有些游覽器,比如firefox,safari(3.1版本之前)會對向上鍵,向下鍵,退格鍵和刪除鍵也會觸發keypress事件了;所以為了避免這些事件的發生,我們需要做一些處理來滿足所有版本的瀏覽器的需求,我們發現在firefox中,所有由非字符鍵觸發keypress鍵碼都為0;而在safari3以前的版本中,對應的字符編碼全部為8;所以我們要對字符編碼進行判斷下;
如下代碼:

EventUtil.addHandler(input,'keypress',
  function(event) { 
    event = EventUtil.getEvent(event);
    var charCode = EventUtil.getCharCode(event);
    if(!/\d/.test(String.fromCharCode(charCode)) && charCode > 9) { 
      EventUtil.preventDefault(event); 
    }
  }
);```
**操作剪貼板**
到目前為止,IE,chrome,safari,opera都支持剪貼板事件,貌似firefox就不支持了(書上說支持);但是我操作就不支持了;下面是6個操作剪貼板事件;如下:
beforecopy: 在發生復制操作前觸發;
copy: 在發生復制操作時觸發;
beforecut: 在發生剪貼操作前觸發;
cut: 在發生剪貼操作時觸發;
beforepaste: 在發生黏貼操作前觸發;
paste: 在發生粘帖操作時觸發;
針對上面的事件,我們可以使用如下代碼測試下就可以證明了;代碼如下所示:

EventUtil.addHandler(input,'beforecopy',
function(event) {
alert(1);
}
);```
如果要訪問剪貼板中的數據,可以使用clipboardData對象,在IE中,這個對象是window對象的屬性,在safari或者chrome上,這個對象是event的屬性,這個clipboardData對象有三個方法,getData(),setData(),和clearData();
getData()是從剪貼板中取得數據,他接受一個參數,即要取得數據的格式,在IE中,有二種數據格式”text” 和 “url”,在safari和chrome中這個參數是一種MIME類型,不過,可以使用text代表text/plain.
setData()方法是給剪貼板設置文本,接受2個參數,第一個數據是數據類型;第二個參數是放在剪貼板中的文本;但是此方法接受的數據類型只能是text/plain,不能是text;因此為了全兼容瀏覽器(出firefox外),我們可以寫一個通用的方法出來,如下:

getClipboardText: function(event) { 
  var clipboardData = (event.clipboardData || window.clipboardData);
  return clipboardData.getData("text"); 
},setClipboardText:function(event,value) {
  if(event.clipboardData) {
    return event.clipboardData.setData("text/plain",value); 
  }else if(window.clipboardData) { 
    return window.clipboardData.setData("text",value); 
  }
}```
因此EventUtil封裝的所有方法如下:

var EventUtil = {
addHandler: function(element,type,handler) {
if(element.addEventListener) {
element.addEventListener(type,handler,false);
}else if(element.attachEvent) {
element.attachEvent("on"+type,handler);
}else {
element["on" +type] = handler;
}
},
removeHandler: function(element,type,handler){
if(element.removeEventListener) {
element.removeEventListener(type,handler,false);
}else if(element.detachEvent) {
element.detachEvent("on"+type,handler);
}else {
element["on" +type] = null;
}
},
getEvent: function(event) {
return event ? event : window.event;
}, getTarget: function(event) {
return event.target || event.srcElement;
}, preventDefault: function(event){
if(event.preventDefault) {
event.preventDefault();
}else {
event.returnValue = false;
}
}, stopPropagation: function(event) {
if(event.stopPropagation) {
event.stopPropagation();
}else {
event.cancelBubble = true;
}
}, getRelatedTarget: function(event){
if (event.relatedTarget){
return event.relatedTarget;
} else if (event.toElement){
return event.toElement;
} else if (event.fromElement){
return event.fromElement;
} else {
return null;
}
}, getWheelDelta: function(event) {
if(event.wheelDelta) {
return event.wheelDelta;
}else {
return -event.detail * 40
}
}, getCharCode: function(event) {
if(typeof event.charCode == 'number') {
return event.charCode;
}else {
return event.keyCode;
}
}, getClipboardText: function(event) {
var clipboardData = (event.clipboardData || window.clipboardData);
return clipboardData.getData("text");
}, setClipboardText:function(event,value) {
if(event.clipboardData) {
return event.clipboardData.setData("text/plain",value);
}else if(window.clipboardData) {
return window.clipboardData.setData("text",value);
}
}
};```
測試代碼如下:還是上面測試輸入框的值是否為數字;每次粘帖上次,都能獲取到黏貼的是文字數據,代碼如下:
HTML代碼如下:

<form id="formId">
<input type="text" name="input"/>
</form>```
JS代碼如下:

var formId = document.getElementById("formId"),
input = formId.elements['input'];
EventUtil.addHandler(input,'paste',function(event){
event = EventUtil.getEvent(event);
var text = EventUtil.getClipboardText(event);
alert(text);
if (!/^\d*$/.test(text)){
EventUtil.preventDefault(event);
}
});```
理解自動切換輸入框或者****textarea****的焦點
比如我們在填寫表單的頁面上,當用戶輸入完自己的數據的時候,不需要用戶手動切換到下一個輸入框里面去,我們可以自動切換去,這樣的話,對于用戶體驗來說,比較方便,比如我們現在頁面上有一個form表單,這里為了做測試,我們先用一個輸入框用于手機號碼的,另外一個是textarea,當手機號碼輸入11位數字后,會自動切換到textarea中;當然頁面中的隱藏域除外;代碼如下:
HTML代碼如下:

<form id="formId"> 
<input type="text" name="input" maxlength=11/> 
<textarea></textarea>
</form>```
JS代碼如下:

var formId = document.getElementById("formId"),
input = formId.elements['input'];
EventUtil.addHandler(input,'keyup',tabForward);
function tabForward(event) {
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
if(target.value.length == target.maxLength) {
// 獲取當前的form表單的引用
var form = target.form;
for(var i=0,ilen=form.elements.length; i<ilen; i++){
if(form.elements[i] == target) {
if(form.elements[i+1]) {
form.elements[i+1].focus();
}
return;
}
}
}
}```
理解HTML5新增屬性
required屬性;
比如在HTML5中對表單input,textarea,或者select標簽的話,提交表單時,需要判斷是否為空,特別對于在做移動端的朋友來說,可以使用HTML5中的新增屬性required;如下HTML代碼:

<form id="formId"> 
<input type="text" name="input" maxlength=11 required/> 
<textarea></textarea> 
<input type="submit"/>
</form>```
提交時候,在chrome下看到效果如下:
![](http://upload-images.jianshu.io/upload_images/2229907-3cb4f0f786a55c25.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
在firefox下,提示如下:
![](http://upload-images.jianshu.io/upload_images/2229907-538edd2d37fd4a6a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
如上是根據不同的瀏覽器本身的性質來提示的,因此樣式不同,所以適合在移動端根據本身瀏覽器內核來提示;
但是在Javascript是如何判斷的呢?比如如下HTML代碼:

<form id="formId">
<input type="text" name="input" maxlength=11 required/>
<textarea></textarea>
<input type="submit" name="submit"/>
</form>```
JS代碼如下:

var formId = document.getElementById("formId"),
  submit = formId.elements['submit'];
  EventUtil.addHandler(submit,'click',function(event){ 
    var isRequired = formId.elements["submit"].required;
    console.log(isRequired);
  });```
如上打印出false;可以獲取到submit的屬性required,如果輸入框值為空的話,會打印出false出來;
如果想知道瀏覽器是否支持required這個屬性的話,我們可以使用如下代碼判斷下,如果返回true,說明支持,否則不支持;如下:

var isRequiredSupported = "required" in document.createElement("input");
console.log(isRequiredSupported);```
input輸入框類型type的值是email或者url
<input type=”email” name=”email”/>
<input type=”url” name=”url”/>
email類型要求輸入的文本必須符合電子郵件的格式,url類型要求輸入的文本必須符合URL的格式;如下chrome瀏覽器截圖如下;



選擇框腳本
選擇框是通過<select>和<option>元素創建的,除了表單所有的共有屬性和方法外,HTMLSelectElement類還提供了下列屬性和方法;
add(newOption,relOption);向控件中插入新<option>元素,其位置在relOption之前;
multiple:布爾值; 表示是否允許多項選擇,等價于HTML中的multiple特性;
**options: **控件中所有<option>元素的HTMLCollection;
**remove(index): **移除給定位置的選項;
**selectedIndex: **基于0的選中索引,如果沒有該選項,則值為 -1;
**size: **選擇框中的可見的行數。
如下select框代碼:

<form id="formId"> 
  <select name="location" id="selLocation"> 
    <option value="A">A</option> 
    <option value="B">B</option> 
    <option value="C">C</option> 
    <option value="">D</option> 
    <option>E</option> 
  </select>
</form>

JS代碼如下:

var formId = document.getElementById("formId"),
  select = formId.elements['location'];
  console.log(select.value);
  EventUtil.addHandler(select,'change',function(){ 
    console.log(select.value)
  });```
第一次頁面加載完成后,打印出值為A;
當每次切換的時候,如果有value就打印出值,如果value=””;則打印空字符串,但是如果option選項沒有指定value,在firfox和chrome下打印出當前的文本值,比如上面的文本為E,則值為E;但是IE8及以下,打印的還是空字符串;
在DOM中,每個<option>元素都有一個HTMLOptionElement對象表示;為方便訪問數據,對象添加了如下屬性;
**index:**當前選項在options集合中的索引;
**label:**當前選項的標簽,等價于HTML中的label
**selected:**布爾值,表示當前選項是否被選中,將這個屬性設置為true可以選中當前選項。
**text:**選項的文本;
**value:**選項的值;
我們還是以上面的form表單作為HTML代碼,我們使用JS來測試下:
如下代碼:

var formId = document.getElementById("formId"),
select = formId.elements['location'];
// 獲取options集合中的第一項選項的文本
console.log(select.options[0].text);
// 打印出A// 獲取options集合中的第一項選項的value
console.log(select.options[0].value);
// 打印出A

對于下拉框只能選擇一項的選擇框,訪問最簡單的方式,就是使用selectedIndex屬性,如下HTML代碼:

<form id="formId">
<select name="location" id="selLocation">
<option value="A">A</option>
<option value="B" selected>B</option>
<option value="C">C</option>
<option value="">D</option>
<option>E</option>
</select>
</form>```
假如頁面初始化的時候默認選擇第二項,那么我們可以先使用selectedIndex的屬性獲取選中的索引,然后根據索引獲取當前的文本和值;如下JS代碼:

var formId = document.getElementById("formId"),
  select = formId.elements['location'];
  // 獲取當前選中的選項的索引selectedIndex
var selectedIndex = select.selectedIndex;
  // 獲取索引為selectedIndex的option
var selectedOption = select.options[selectedIndex];
console.log("selected index:"+selectedIndex+"\nselect text:"+selectedOption.text+"\nselect value:"+selectedOption.value);```
**添加選項**
可以使用javascript動態創建選項,并將它們添加到選擇框中,添加選擇框有以下常見3種方式;
第一種方式使用DOM的方式如下:
HTML代碼如下:

<form id="formId">
<select name="location" id="selLocation"></select>
</form>```
JS代碼如下:

var formId = document.getElementById("formId"),
  select = formId.elements['location'];
var newOption = document.createElement("option");
newOption.appendChild(document.createTextNode("A"));
newOption.setAttribute("value","AAAA");
select.appendChild(newOption);```
第二種方式使用Option構造函數來創建新選項,Option構造函數接收2個參數,文本(text)和值(value),第二個參數可選,比如如下代碼:

var formId = document.getElementById("formId"),
select = formId.elements['location'];
var newOption = new Option("Option text","Option value");
select.appendChild(newOption);```

但是這種方式在IE下是不生效的;
下面我們來看看第三種方式吧!是使用選擇框add()方法,DOM規定這個方法接收2個參數,要添加的新選項和將位于新選項之后的選項,如果想在列表的最后添加一個選項,應將第二個參數設置為null;在IE對add()方法的實現中,第二個參數是可選的,但是標準DOM瀏覽器中,必須要指定第二個參數,因此為了全兼容瀏覽器,我們必須添加第二個參數,但是我們可以將第二個參數設置為undefined,含義是:在所有的瀏覽器將新選項插入到列表的最后了~
如下代碼:

var formId = document.getElementById("formId"),
  select = formId.elements['location'];
var newOption = new Option("Option text","Option value");
select.add(newOption,undefined);```
**移除選項的方式如下:**
1. 使用dom的removeChild()方法,為其傳入要移除的選項;如下代碼:
HTML代碼如下:

<form id="formId">
<select name="location" id="selLocation">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
</form>

Javascript代碼如下:

var formId = document.getElementById("formId"),
select = formId.elements['location'];
// 第一種:移除第一項如下方式
select.removeChild(select.options[0]);```

  1. 第二種方式是使用選擇框的remove()方法,這個方法接收一個參數,既要移除選項的索引;如下代碼:
var formId = document.getElementById("formId"),select = formId.elements['location'];// 移除第一項select.remove(0);```

3. 最后一種方式,就是將相應的選項設置為null,如下代碼:

var formId = document.getElementById("formId"),
select = formId.elements['location'];
// 移除第一項
select.options[0] = null;```

理解表單序列化
在javascript中,可以利用表單字段的type屬性,連同name和value屬性一起實現對表單的序列化,序列化后將把這些數據發送給服務器。
下面是將那些字段需要進行序列化的;

1.對表單字段的名稱和值進行URL編碼,使用&分割;
2.不發送禁用的表單字段;
3.只發送勾選的單選框和復選框按鈕數據;
4.不發送type為reset和button的按鈕
5.多選選擇框中的每個選中的值單獨一個條目;
6.Select元素的值,就是選中option元素的value的值,如果option沒有屬性value,則是選中的文本值;

如下JS代碼是封裝form表單的序列化的JS如下:
// 序列化JS代碼封裝

function serialize(form) { 
  var arrs = [], field = null, i, len, j, optLen, option, optValue;
  for(i = 0,len = form.elements.length; i < len; i++) {
    field = form.elements[i]; 
    switch(field.type) { 
      case "select-one": case "select-multiple":   
        if(field.name.length) { 
          for(j = 0,optLen = field.options.length; j < optLen; j++) {
            option = field.options[j]; 
            if(option.selected) { 
              optValue = ''; 
              if(option.hasAttribute) { 
                optValue = option.hasAttribute("value") ? option.value : option.text; 
              }else { 
                optValue = option.attributes["value"].specified ? option.value : option.text; 
              }
            arrs.push(encodeURIComponent(field.name) + "=" +encodeURIComponent(optValue));
            } 
          } 
        } 
        break; 
        case undefined: 
        //字段集 
        case "file": 
        // 文件輸入 
        case "submit": 
        // 提交按鈕 
        case "reset": 
        // 重置按鈕 
        case "button": 
        // 自定義按鈕 
        break;
        case "radio": 
        // 單選框 
        case "checkbox": 
        // 復選框 
          if(!field.checked) { 
            break; 
          } 
      /* 執行默認動作 */
        default: 
      // 不包含沒有名字的表單字段 
          if(field.name.length) {
            arrs.push(encodeURIComponent(field.name) + "=" +encodeURIComponent(field.value)); 
          } 
        } 
      } 
    return arrs.join("&");
  }```
如上對form表單序列化的函數serialize,定義了一個arrs數組,用來保存需要序列化后的名值對,然后通過for循環迭代每個表單中的字段,先使用臨時變量field保存表單中任意一個字段的引用,然后使用switch語句判斷字段的類型type(如果type未定義的話,此元素就不需要表單序列化),第一種情況是select的單選和多選框,對于select單選框,只可能有一個選中項,對于多選框可能有零或多個選中項,如果有選中項的話(通過屬性selected來判斷),需要確定使用什么值,如果不存在value特性,或者雖然存在該特性,但是值為空字符串,都是使用選項的文本來代替,為檢查這個特性,在兼容DOM的瀏覽器下我們需要使用hasAttribute()方法,而在IE中需要使用特性的specified屬性;對于type=“file”或者submit,reset,button等就不支持,如果比如上傳圖片的時候,需要圖片的二進制數據使用form表單提交的話,可以在序列化后在加上這個參數即可;對于單選框和復選框如果沒有選中的話,同樣不進行序列化;下面我們現在來看看一個demo吧!如下HTML代碼:

<form id="formId">
<select name="location" id="selLocation" one="one">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
<select multiple="multiple" style="width: 50px;" id="mymultiple" name="select2">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
<input name="a" type="radio"/>
<input name="b" type="checkbox"/>
<input type="file" name="aaaa">
<input type="hidden" name="hidden" value="hidden"/>
<input type="submit" value="提交" name="submit"/>
</form>```
JS代碼如下:

var formId = document.getElementById("formId");
console.log(serialize(formId));
var submit = formId.elements['submit'];
EventUtil.addHandler(submit,'click',function(e){
    EventUtil.preventDefault(e);
    console.log(serialize(formId));
});```
我們看到上面的form表單代碼,上面有select單選框,也有select多選框,也有隱藏域和input框,**但是請注意:**上面name=”a”和name=”b”,當他們選中的時候,沒有值屬性,所以在各個瀏覽器上都會自帶一個值為on的值傳給服務器端,但是這個并不是我們想要的,所以的如果需要值的話,一定要設置值,如下如下截圖:
在火狐和谷歌下截圖如下:
![](http://upload-images.jianshu.io/upload_images/2229907-79e597865f688c68.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
在IE下:
![](http://upload-images.jianshu.io/upload_images/2229907-cf4c14a9c8e6edbd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
上面的select多選框,如果需要多選的話,記得先要按住鍵盤上的ctrl鍵就可以多選了,比如上面的select2=2&select2=3&select2=4 就是select框多選。
**理解富文本編輯**
在網頁中編輯內容,IE最早引入這個功能,隨后opera,safari,firefox和chrome也實現了這個功能,基本原理就是在頁面中嵌入一個空HTML頁面的iframe,通過設置designMode屬性,這個空白的HTML頁面可以添加文字,而添加文字則是該頁面的body元素的html代碼,如下所示:
![](http://upload-images.jianshu.io/upload_images/2229907-753e2f8d4d74439a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
designMode有2個屬性,off(默認值)和on, 當設置為on的時候,整個文檔變得可編輯,但是我們也可以給他們添加css樣式,為了更加美觀;首先我們先來看看demo,如下HTML頁面嵌套一個iframe;
<iframe name="richedit" src="bank.html"></iframe>
而bank.html頁面是一個空頁面,代碼如下:

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus?">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>Document</title>
</head>
<body> ```
然后在主頁面上使用JS,當頁面加載完成后,將designMode屬性設置為on即可,如下JS代碼:

EventUtil.addHandler(window,'load',function(event){ 
  frames['richedit'].document.designMode = "on";
});

然后在頁面上顯示如下:


第二種實現方式是使用contenteditable屬性來實現
contenteditable屬性是有IE最早實現的,可以把contenteditable屬性給頁面中的任何元素,然后用戶可以立即編輯該元素,不需要iframe,空頁面及JS,只需要使用contenteditable屬性即可;如下代碼給div設置contenteditable屬性;如下代碼:

<div class="richedit" contenteditable style="width:100px;height:100px;border:1px solid #ccc">
</div>```
在瀏覽器下效果如下:
![](http://upload-images.jianshu.io/upload_images/2229907-dcd9a1fcdd491533.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
支持的瀏覽器有;IE,firefox,chrome,safari和opera;
在移動設備上,有ios5+和Android3+;
Contenteditable屬性有三個可能值,true表示打開,false表示關閉,inherit表示從父元素那邊繼承。
[轉載自:空智的博客](http://www.cnblogs.com/tugenhua0707/p/4508986.html)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 表單基礎知識 在HTML中,表單是由 元素來表示的,而在JS中,表單對應的則是HTMLFormElement類型。...
    oWSQo閱讀 920評論 0 1
  • HTML表單 在HTML中,表單是 ... 之間元素的集合,它們允許訪問者輸入文本、選擇選項、操作對象等等,然后將...
    蘭山小亭閱讀 3,439評論 2 14
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,796評論 1 92
  • 這篇文章的主人公叫荔枝 三個月 我們彼此認識11天 在11天里 我們在醫院共同奮戰了6天 然后他度過了他短暫而又痛...
    我想養的貓超級酷閱讀 384評論 0 0
  • 最近,網絡上一則有關平腦癥嬰兒的消息引起了很多人的關注。國外一對夫婦,Brandon跟Brittany結婚后,懷上...
    meikoyunying閱讀 1,189評論 0 1