為了分擔服務器處理表單的壓力,JavaScript提供了一些解決方案,從而大大打破了處處依賴服務器的局面。
發文不易,轉載請親注明出處,謝謝!
一.表單介紹
在HTML中,表單是由<form>元素來表示的,而在JavaScript中,表單對應的則是HTMLFormElement類型。HTMLFormElement繼承了HTMLElement,因此它擁有HTML元素具有的默認屬性,並且還獨有自己的屬性和方法:
HTMLFormElement屬性和方法
屬性或方法 |
說明 |
acceptCharset |
服務器能夠處理的字符集 |
action |
接受請求的URL |
elements |
表單中所有控件的集合 |
enctype |
請求的編碼類型 |
length |
表單中控件的數量 |
name |
表單的名稱 |
target |
用於發送請求和接受響應的窗口名稱 |
reset() |
將所有表單重置 |
submit() |
提交表單 |
獲取表單<form>對象的方法有很多種,如下:
document.getElementById('myForm'); //使用ID獲取<form>元素
document.getElementsByTagName('form')[0]; //使用獲取第一個元素方式獲取
document.forms[0]; //使用forms的數字下標獲取元素
document.forms['yourForm']; //使用forms的名稱下標獲取元素
document.yourForm; //使用name名稱直接獲取元素(不推薦)
PS:最后一種方法使用name名稱直接獲取元素,已經不推薦使用,這是向下兼容的早期用法。問題頗多,比如有兩個相同名稱的,變成數組;而且這種方式以后有可能會不兼容。
提交表單
通過事件對象,可以阻止submit的默認行為,submit事件的默認行為就是攜帶數據(默認以get方式)跳轉到指定頁面(默認為本頁)。
addEvent(fm, 'submit', function (evt) { //注意是在form對象上觸發submit事件
preDef(evt);
});
PS:submit事件,用傳統的方式:fm.onsubmit = function () {}。
PS:必須把submit事件綁定到form對象上,才可以觸發submit事件,只不過觸發submit事件的流程是點擊input中的submit按鈕而已。
我們可以使用submit()方法來自定義觸發submit事件,也就是說,並不一定非要點擊submit按鈕才能提交。示例代碼如下:
//實現ctrl+enter實現提交
1 addEvent(document, 'keydown', function (evt) { 2 3 var e = evt || window.event; 4 5 if (e.ctrlKey && e.keyCode == 13) fm.submit(); 6 7 });
PS:在表單中盡量避免使用name="submit"或id="submit"等命名,這會和submit()方法發生沖突導致無法提交。
提交數據最大的問題就是重復提交表單。因為各種原因,當一條數據提交到服務器的時候會出現延遲等長時間沒反映,導致用戶不停的點擊提交,從而使得重復提交了很多相同的請求,或造成錯誤、或寫入數據庫多條相同信息。
//模擬延遲
1 addEvent(fm, 'submit', function (evt) { 2 3 preDef(evt); //先阻止提交 4 5 setTimeout(function () { 6 7 fm.submit(); //提交 8 9 }, 3000); //3秒鍾之后才發送數據(延遲就可能會導致,用戶不停地點擊提交) 10 11 });
有兩種方法可以解決這種問題:
第一種就是提交之后,立刻禁用點擊按鈕;
第二種就是提交之后取消后續的表單提交操作。
法1:
document.getElementById('sub').disabled = true; //將按鈕禁用(僅限於使用提交按鈕進行提交的形式)
法2:
1 var fm = document.getElementById('myForm'); 2 3 var flag = false; //設置一個監聽變量 4 5 addEvent(fm, 'submit', function (evt) { 6 7 preDef(evt); 8 9 if (flag == true) return; //如果存在返回退出事件 10 11 flag = true; //否則確定是第一次,設置為true,表示我提交過一次了 12 13 alert('提交'); 14 15 setTimeout(function () { 16 17 fm.submit(); 18 19 }, 3000); 20 21 }); 22 23
PS:在某些瀏覽器,F5只能起到緩存刷新的效果(淺刷新),有可能獲取不到真正的源頭更新的數據。那么使用ctrl+F5就可以把源頭給刷出來。
重置表單
用戶點擊重置按鈕時,表單會被初始化。雖然這個按鈕還得以保留,但目前的Web已經很少去使用了。因為用戶已經填寫好各種數據,不小心點了重置就會全部清空,用戶體驗極差。
有兩種方法調用reset事件:
第一個就是直接type="reset"即可;
第二個就是使用fm.reset()方法調用即可。
法1:
<input type="reset" value="重置" /> //不需要JS代碼即可實現
法2:
addEvent(document,'click', function () {
fm.reset(); //使用JS方法實現重置
});
表單字段
如果想訪問表單元素,可以使用之前章節講到的DOM方法訪問。但使用原生的DOM訪問雖然比較通用,但不是很便利。表單處理中,我們建議使用HTML DOM,它有自己的elements屬性,該屬性是表單中所有元素的集合。
PS:表單控件是什么? form里面的input,submit,textarea,select 這些叫做表單控件,其實就是表單元素標簽,通過表單元素集合獲取第一個元素,非表單控件會被忽略掉。
fm.elements[0]; //獲取第一個表單字段元素
fm.elements['user']; //獲取name是user的表單字段元素
fm.elements.length; //獲取所有表單字段的數量
如果多個表單字段都使用同一個name,那么就會返回該name的NodeList表單列表。
fm.elements['sex']; //獲取相同name表單字段列表
PS:我們是通過fm.elements[0]來獲取第一個表單字段的,但也可以使用fm[0]直接訪問第一個字段。因為fm[0]訪問方式是為了向下兼容的,所以,我們建議大家使用elements屬性來獲取。
共有的表單字段屬性
除了<fieldset>元素之外,所有表單字段都擁有相同的一組屬性。由於<input>類型可以表示多種表單字段(由type屬性決定),因此有些屬性只適用於某些字段。以下羅列出共有的屬性:
屬性或方法 |
說明 |
disabled |
布爾值,表示當前字段是否被禁用 |
form |
指向當前字段所屬表單的指針,只讀 |
name |
當前字段的名稱 |
readOnly |
布爾值,表示當前字段是否只讀 |
tabIndex |
表示當前字段的切換 |
type |
當前字段的類型 |
value |
當前字段的值 |
這些屬性其實就是HTML表單里的屬性,在XHTML相關知識中有詳細介紹(自行查閱),這里不作贅述,重點看幾個最常用的:
fm.elements[0].value; //獲取和設置value
fm.elements[0].form == fm; //查看當前字段所屬表單
fm.elements[0].disabled = true; //禁用當前字段
fm.elements[0].type = 'checkbox'; //修改字段類型,極不推薦!
除了<fieldset>字段之外,所有表單字段都有type屬性。對於<input>元素,這個值等於HTML屬性的type值。對於非<input>元素,這個type的屬性值如下:
非<input>元素的type屬性值
元素說明 |
HTML標簽 |
type屬性的值 |
單選列表 |
<select>...</select> |
select-one |
多選列表 |
<select multiple>...</select> |
select-multiple |
自定義按鈕 |
<button>...</button> |
button |
自定義非提交按鈕 |
<button type="button">...</button> |
button |
自定義重置按鈕 |
<button type="reset">...</button> |
reset |
自定義提交按鈕 |
<button type="submit">...</button> |
submit |
PS:<input>和<button>元素的type屬性是可以動態修改的,而<select>元素的type屬性則是只讀的。(在不必要的情況下,建議不修改type)。
共有的表單字段方法
每個表單字段都有兩個方法:foucs()和blur()。
方法 |
說明 |
focus() |
將焦點定位到表單字段里 |
blur() |
從元素中將焦點移走 |
fm.elements[0].focus(); //將焦點移入
fm.elements[0].blur(); //將焦點移出
共有的表單字段事件
表單共有的字段事件有以下三種:
事件名 |
說明 |
blur |
當字段失去焦點時觸發 |
change |
對於<input>和<textarea>元素,在改變value並失去焦點時觸發;對於<select>元素,在改變選項時觸發 |
focus |
當前字段獲取焦點時觸發 |
addEvent(textField, 'focus', function () { //緩存blur和change再測試一下
alert('Mr.Lee');
});
PS:關於blur和change事件的關系,並沒有嚴格的規定。在某些瀏覽器中,blur事件會先於change事件發生;而在其他瀏覽器中,則恰好相反。
---恢復內容結束---
為了分擔服務器處理表單的壓力,JavaScript提供了一些解決方案,從而大大打破了處處依賴服務器的局面。
發文不易,轉載請親注明出處,謝謝!
一.表單介紹
在HTML中,表單是由<form>元素來表示的,而在JavaScript中,表單對應的則是HTMLFormElement類型。HTMLFormElement繼承了HTMLElement,因此它擁有HTML元素具有的默認屬性,並且還獨有自己的屬性和方法:
HTMLFormElement屬性和方法
屬性或方法 |
說明 |
acceptCharset |
服務器能夠處理的字符集 |
action |
接受請求的URL |
elements |
表單中所有控件的集合 |
enctype |
請求的編碼類型 |
length |
表單中控件的數量 |
name |
表單的名稱 |
target |
用於發送請求和接受響應的窗口名稱 |
reset() |
將所有表單重置 |
submit() |
提交表單 |
獲取表單<form>對象的方法有很多種,如下:
document.getElementById('myForm'); //使用ID獲取<form>元素
document.getElementsByTagName('form')[0]; //使用獲取第一個元素方式獲取
document.forms[0]; //使用forms的數字下標獲取元素
document.forms['yourForm']; //使用forms的名稱下標獲取元素
document.yourForm; //使用name名稱直接獲取元素(不推薦)
PS:最后一種方法使用name名稱直接獲取元素,已經不推薦使用,這是向下兼容的早期用法。問題頗多,比如有兩個相同名稱的,變成數組;而且這種方式以后有可能會不兼容。
提交表單
通過事件對象,可以阻止submit的默認行為,submit事件的默認行為就是攜帶數據(默認以get方式)跳轉到指定頁面(默認為本頁)。
addEvent(fm, 'submit', function (evt) { //注意是在form對象上觸發submit事件
preDef(evt);
});
PS:submit事件,用傳統的方式:fm.onsubmit = function () {}。
PS:必須把submit事件綁定到form對象上,才可以觸發submit事件,只不過觸發submit事件的流程是點擊input中的submit按鈕而已。
我們可以使用submit()方法來自定義觸發submit事件,也就是說,並不一定非要點擊submit按鈕才能提交。示例代碼如下:
//實現ctrl+enter實現提交
1 addEvent(document, 'keydown', function (evt) { 2 3 var e = evt || window.event; 4 5 if (e.ctrlKey && e.keyCode == 13) fm.submit(); 6 7 });
PS:在表單中盡量避免使用name="submit"或id="submit"等命名,這會和submit()方法發生沖突導致無法提交。
提交數據最大的問題就是重復提交表單。因為各種原因,當一條數據提交到服務器的時候會出現延遲等長時間沒反映,導致用戶不停的點擊提交,從而使得重復提交了很多相同的請求,或造成錯誤、或寫入數據庫多條相同信息。
//模擬延遲
1 addEvent(fm, 'submit', function (evt) { 2 3 preDef(evt); //先阻止提交 4 5 setTimeout(function () { 6 7 fm.submit(); //提交 8 9 }, 3000); //3秒鍾之后才發送數據(延遲就可能會導致,用戶不停地點擊提交) 10 11 });
有兩種方法可以解決這種問題:
第一種就是提交之后,立刻禁用點擊按鈕;
第二種就是提交之后取消后續的表單提交操作。
法1:
document.getElementById('sub').disabled = true; //將按鈕禁用(僅限於使用提交按鈕進行提交的形式)
法2:
1 var fm = document.getElementById('myForm'); 2 3 var flag = false; //設置一個監聽變量 4 5 addEvent(fm, 'submit', function (evt) { 6 7 preDef(evt); 8 9 if (flag == true) return; //如果存在返回退出事件 10 11 flag = true; //否則確定是第一次,設置為true,表示我提交過一次了 12 13 alert('提交'); 14 15 setTimeout(function () { 16 17 fm.submit(); 18 19 }, 3000); 20 21 }); 22 23
PS:在某些瀏覽器,F5只能起到緩存刷新的效果(淺刷新),有可能獲取不到真正的源頭更新的數據。那么使用ctrl+F5就可以把源頭給刷出來。
重置表單
用戶點擊重置按鈕時,表單會被初始化。雖然這個按鈕還得以保留,但目前的Web已經很少去使用了。因為用戶已經填寫好各種數據,不小心點了重置就會全部清空,用戶體驗極差。
有兩種方法調用reset事件:
第一個就是直接type="reset"即可;
第二個就是使用fm.reset()方法調用即可。
法1:
<input type="reset" value="重置" /> //不需要JS代碼即可實現
法2:
addEvent(document,'click', function () {
fm.reset(); //使用JS方法實現重置
});
表單字段
如果想訪問表單元素,可以使用之前章節講到的DOM方法訪問。但使用原生的DOM訪問雖然比較通用,但不是很便利。表單處理中,我們建議使用HTML DOM,它有自己的elements屬性,該屬性是表單中所有元素的集合。
PS:表單控件是什么? form里面的input,submit,textarea,select 這些叫做表單控件,其實就是表單元素標簽,通過表單元素集合獲取第一個元素,非表單控件會被忽略掉。
fm.elements[0]; //獲取第一個表單字段元素
fm.elements['user']; //獲取name是user的表單字段元素
fm.elements.length; //獲取所有表單字段的數量
如果多個表單字段都使用同一個name,那么就會返回該name的NodeList表單列表。
fm.elements['sex']; //獲取相同name表單字段列表
PS:我們是通過fm.elements[0]來獲取第一個表單字段的,但也可以使用fm[0]直接訪問第一個字段。因為fm[0]訪問方式是為了向下兼容的,所以,我們建議大家使用elements屬性來獲取。
共有的表單字段屬性
除了<fieldset>元素之外,所有表單字段都擁有相同的一組屬性。由於<input>類型可以表示多種表單字段(由type屬性決定),因此有些屬性只適用於某些字段。以下羅列出共有的屬性:
屬性或方法 |
說明 |
disabled |
布爾值,表示當前字段是否被禁用 |
form |
指向當前字段所屬表單的指針,只讀 |
name |
當前字段的名稱 |
readOnly |
布爾值,表示當前字段是否只讀 |
tabIndex |
表示當前字段的切換 |
type |
當前字段的類型 |
value |
當前字段的值 |
這些屬性其實就是HTML表單里的屬性,在XHTML相關知識中有詳細介紹(自行查閱),這里不作贅述,重點看幾個最常用的:
fm.elements[0].value; //獲取和設置value
fm.elements[0].form == fm; //查看當前字段所屬表單
fm.elements[0].disabled = true; //禁用當前字段
fm.elements[0].type = 'checkbox'; //修改字段類型,極不推薦!
除了<fieldset>字段之外,所有表單字段都有type屬性。對於<input>元素,這個值等於HTML屬性的type值。對於非<input>元素,這個type的屬性值如下:
非<input>元素的type屬性值
元素說明 |
HTML標簽 |
type屬性的值 |
單選列表 |
<select>...</select> |
select-one |
多選列表 |
<select multiple>...</select> |
select-multiple |
自定義按鈕 |
<button>...</button> |
button |
自定義非提交按鈕 |
<button type="button">...</button> |
button |
自定義重置按鈕 |
<button type="reset">...</button> |
reset |
自定義提交按鈕 |
<button type="submit">...</button> |
submit |
PS:<input>和<button>元素的type屬性是可以動態修改的,而<select>元素的type屬性則是只讀的。(在不必要的情況下,建議不修改type)。
共有的表單字段方法
每個表單字段都有兩個方法:foucs()和blur()。
方法 |
說明 |
focus() |
將焦點定位到表單字段里 |
blur() |
從元素中將焦點移走 |
fm.elements[0].focus(); //將焦點移入
fm.elements[0].blur(); //將焦點移出
共有的表單字段事件
表單共有的字段事件有以下三種:
事件名 |
說明 |
blur |
當字段失去焦點時觸發 |
change |
對於<input>和<textarea>元素,在改變value並失去焦點時觸發;對於<select>元素,在改變選項時觸發 |
focus |
當前字段獲取焦點時觸發 |
addEvent(textField, 'focus', function () { //緩存blur和change再測試一下
alert('Mr.Lee');
});
PS:關於blur和change事件的關系,並沒有嚴格的規定。在某些瀏覽器中,blur事件會先於change事件發生;而在其他瀏覽器中,則恰好相反。
未完待續······(下一篇:JavaScript表單處理(下)http://www.cnblogs.com/ttcc/p/3772024.html)