form 表單 那點 事兒 進階 欄目 HTML 简体版
原文   原文鏈接

上一篇主要溫習了一下form表單的屬性和表單元素,這一片主要講解用JavaScript如何操做form。javascript

表單操做

取值

用JavaScript操做表單,免不了會有取值賦值操做,好比有如下表單:html

<form id='form0'></form>
  
  <form action="/login" method="post" target="blank" id='form1'>
  
    <input type="text" name='user_name'>  <!--field 0-->
    <input type="email" name='user_email'>  <!--field 1-->
    <select  name='user_phone'>  <!--field 2-->
      <option value='1'>13333333331</option>
      <option value='2'>13333333332</option>
      <option value='3'>13333333333</option>
    </select>
    <input type="text" name='form0_user_phone' form='form0'>  <!--field 3-->
    <button type='submit' form='form0'>預覽</button>  <!--field 4-->
    
    <button type='submit'>提交</button>  <!--field 5-->
    
  </form>

用JavaScript獲取表單的屬性值,或者表單字段的值,能夠直接經過 elem.name 的方式html5

alert(form1.action); => '/login'
alert(form1.method); => 'post'
alert(form1.user_name.value) => ''

而要獲取表單中的字段,則經過:java

// 屬於本表單元素nodelist類數組,若是經過form屬性指定到其餘表單,不會算做本表單元素,下面獲取到的元素是field 0,field 1,field 2,field 5
console.log(form1.elements);  => [<input>...,...,...</button>] 

// 屬於本表單元素個數,若是經過form屬性指定到其餘表單,不會算做本表單元素
console.log(form1.length);  => 4 

// nodelist中下標爲2的表單元素
console.log(form1[1]);  => <input type="email" name='user_email'>

// 表單中 name='user_name' 的元素,有同名的字段則返回一個nodelst類數組
console.log(form1['user_name']);  => <input type="text" name='user_name'> 或 nodelist

// 獲取表單所有內容,詳情見下面的 「提交」 條目
jQuery('#form1').serialize(); => user_name=&user_email=&user_phone=13333333331
jQuery('#form1').serializeArray(); => [] 一個數組,裏面是每一個字段的鍵值對
new FormData(form1) => 沒有返回值

賦值

表單自己的屬性能夠經過JavaScript賦值,好比 action , method , target 等。例如node

// 把表單提交到 "/signIn"
form1.action = '/signIn';

// 修改表單提交方式爲 "GET"
form1.method = 'GET';

而給表單元素賦值,則是經過 elem.value 的方式,例如jquery

// 將user_name的值設定爲 "hello world"
form1.user_name.value = "hello world"; 

// 選中select中值爲2的option
form1.user_phone.value = 2;

重置

能夠經過html或者JavaScript的方式把表單值重置爲頁面初始的樣子。
html方式爲點擊 type='reset'inputbutton。JavaScript的方式爲 form1.reset()
若是表單中應用了第三方UI庫如 select2 ,重置後還須要手動觸發表單元素的change事件,以觸發第三方庫更新UI。經常使用的方式是:git

form1.reset();
$(form1.user_phone).change();

校驗

傳統校驗

傳統的表單校驗方式是經過監聽的 submit 事件或是表單字段的 input , focus , blur , change 事件,去觸發JavaScript中指定的校驗規則,來肯定表單是提交仍是拒絕提交。github

html5校驗

步入html5時代以後,能夠僅經過html自己完成表單提交前的校驗工做。方式是給表單字段加上 requiredpattern 屬性,required 是告訴瀏覽器這個字段須要校驗,而 pattern 則指定一個正則表達式形式的校驗規則。在表單提交時,瀏覽器會自動進行一系列的校驗工做,沒有經過校驗的表單是沒法提交到服務器的。
想要手動檢查整個表單是否經過了校驗規則,能夠經過 form.checkValidity() 方法,它會返回一個布爾值。ajax

比較知名的表單校驗插件是 jquery-validation正則表達式

提交

提交規則

提交表單時,表單擁有的字段會按照method中的指定方式提交給服務器,而表單提交的字段規則是:

表單元素 type
規則
<input>
button
永遠不提交
<input> checkbox 只在勾選後提交
<input> file 永遠提交,即便爲空值
<input> hidden 永遠提交,即便爲空值
<input> image 永遠提交,即便爲空值
<input> password 永遠提交,即便爲空值
<input> radio 只在勾選後提交,若是一組Radio沒有任何勾選,所有不提交。
<input> reset 永遠不提交
<input> submit 點擊哪一個按鈕,則提交這個按鈕的值,其餘的SUBMIT按鈕值都不提交。
若是表單的提交行爲是由JavaScript腳本觸發的,則不提交任何值。
<input> text 永遠提交,即便爲空值
<button>
button
永遠不提交
<button> reset 永遠不提交
<button> submit 點擊哪一個按鈕提交表單,則提交這個按鈕的值。
若是省略TYPE,IE默認爲BUTTON,火狐默認SUBMIT。
<select>
-
永遠提交,即便爲空值。
<textarea>
- 永遠提交,即便爲空值。

表格中沒有提到的規則還有:

規則來源 http://www.cnblogs.com/manors/archive/2010/03/11/1683727.html

表單序列化

GET方法提交表單,表單字段會被encodeURIComponent轉換,並在url中顯示出來。而post方法提交表單,會在請求body中發送表單字段鍵值對。

在經過JavaScript異步提交表單時,如何按照上面的規則去獲取表單數據,jquery提供了 serialize()serializeArray() 兩個方法。使用該方法會取得和原生表單一致的提交字段。

表單提交事件

表單提交到服務器時,會觸發 submit 事件。也能夠經過 form.submit() 手動提交一個表單。

form1.onsubmit = function(event){
   event.preventDefault(); // 阻止默認事件,表單將不會提交到服務器
   if(confirm('你真的要提交我嗎~')){
     this.submit(); // 點擊肯定後,表單會被提交
   }
}

技巧

不提交空字段

經過上方的表單提交規則能夠知道,不少時候,不管是否填寫了值,在提交的時候,該字段都會被提交到服務器。而在執行條件篩選表單提交的時候,因爲經常使用的是GET請求,瀏覽器地址欄中一般會出現一長串字符。
這對於有潔癖的用戶來講是沒法忍受的,因此須要在提交表單前作一點小動做,讓值爲空的字段不提交到服務器。

// 本段代碼使用了jquery

var form = $('form'),
    fields = form.find(':input');
 
form.on('submit',function(event){
   event.preventDefault(); // 阻止默認事件,表單將不會提交到服務器
   fields.each(function(){
     if(!this.value.length) this.disabled = 'disabled'; // 含有disabled屬性的表單字段將不會被提交
   });
   this.submit();
})

異步提交文件

通常而言,文件提交都是同步的,由於通常的表單序列化方法,沒法傳輸二進制的文件。而若是要實現異步上傳文件的需求,主要依靠兩種方式。
一種是新建一個 iframe ,在裏面經過一個獨立的form表單上傳文件後,再和主frame進行通訊。另外一種則是經過html5的 new FormData() 方法,append進去一個文件,或是直接讀取表單信息。
利用 iframe 方式提交文件的較爲知名的插件是 jquery.form.js 。經過 new FormData() 則簡單了許多:

# 這是一個來自 MDN 的示例

// 原生JavaScript方式
var xhr = new XMLHttpRequest();
xhr.open("POST", form1.action);
xhr.send(new FormData(form1));

// 使用jquery的ajax()
$.ajax({
  url: form1.action,
  type: "POST",
  data: new FormData(form1),
  processData: false,  // 告訴jQuery不要去處理髮送的數據
  contentType: false   // 告訴jQuery不要去設置Content-Type請求頭
});

更多用法請參考 MDN--使用FormData對象

許多專門作文件上傳的插件,會同時使用兩種上傳方式,以兼容不一樣瀏覽器。

參考資料

MDN

w3.org

相關文章
相關標籤/搜索
每日一句
    每一个你不满意的现在,都有一个你没有努力的曾经。
本站公眾號
   歡迎關注本站公眾號,獲取更多信息