s表單驗證:通過document.forms['表單名'] \['元素名']
```
<!DOCTYPE html>
<html>
<head>
<title>表單驗證</title>
</head>
<body>
<form name="myform" action="demo.py" onsubmit="return validateForm()" method="post">
名字:<input type="text" name="fname">
<input type="submit" value="提交">
</form>
</body>
</html>
<script type="text/javascript">
function validateForm() {
var val=document.forms['myform']['fname'].value;
if (val==''||val==null) {
alert('名字不能為空')
return false;
}
}
</script>
```

HTML表單自動驗證:表單的驗證可以通過瀏覽器來自動完成。如果表單字段的值為空,**required**屬性會阻止表單提交
```
名字:<input type="text" name="uname" required="required">
```
##### 數據驗證
數據驗證用來確保用戶輸入的數據是有效的,典型的數據驗證有:
- 必須字段是否有輸入
- 用戶是否輸入了合法數據
- 在數字字段是否輸入了文本
- 驗證是否是一個正確的email地址
- 日期是否輸入正確
js約束驗證DOM方法:
checkValidity():如果input元素中的數據是合法的返回true,否則返回false。
setCustomValidity()設置input元素的validationMessage屬性,用于定義錯誤提示信息的方法
在js中this關鍵字不是固定不變的,它會隨著執行環節的改變而改變,ES2015(ES6) 新增加了兩個重要的 JavaScript 關鍵字: let 和 const。let 聲明的變量只在 let 命令所在的代碼塊內有效。const 聲明一個只讀的常量,一旦聲明,常量的值就不能改變。在 ES6 之前,JavaScript 只有兩種作用域: 全局變量 與 函數內的局部變量。
const用于聲明一個或多個常量,聲明必須初始化,且初始化后值不可再修改。Json格式:json是一種輕量級的數據交換格式。json數據格式為鍵值對形式。將json字符串轉換為javascript對象:使用js內置函數JSON.parse()將字符串轉為javaScript對象,JSON。stringify()將JavaScript轉為json字符
內容是《Web前端開發之Javascript視頻》的課件,請配合大師哥《Javascript》視頻課程學習。
表單校驗可以確保用戶以正確的格式填寫表單數據,確保提交的數據能使應用程序正常工作;
當輸入數據時,Web應用會驗證輸入的數據是否是正確;如果驗證通過,應用允許提交這些數據到服務器端并儲存到數據庫中,如果驗證未通過,則應用會提示有錯誤的數據,并且一般都會明確的提示錯誤發生在哪里;
表單的數據校驗的作用:
希望以正確的格式獲取到正確的數據:如果用戶的數據以不正確的格式存儲,或者沒有輸入正確的信息或都沒有輸入信息,Web應用程序將無法正常運行;
保護用戶的信息安全:強制用戶輸入安全的密碼,有利于保護他們的賬戶信息;
保障網站的安全:惡意用戶有很多通過濫用應用中缺乏保護的表單破壞應用的方法;
表單數據校驗的方式:
表單校驗可以通過許多不同的方式實現,主要是兩端校驗;
客戶端校驗:
發生在瀏覽器端,表單數據被提交到服務器之前,這種方式相較于服務器端校驗來說,用戶體驗更好,它能實時的反饋用戶的輸入校驗結果,這種類型的校驗可以進一步細分以下方式:
JavaScript校驗:利用Javascript,可以完全自定義校驗表單數據的實現方式;
HTML5約束校驗:也就是HTML5內置的校驗,其不需要JavaScript,而且性能更好,但是不如JavaScript校驗那樣可以自定義,靈活性不夠;
服務器端校驗:
發生在瀏覽器提交數據并被服務器端接收之后;通常服務器端校驗都是發生在將數據寫入數據庫之前,如果數據沒通過校驗,則會直接從服務器端返回錯誤消息,并且告訴瀏覽器端發生錯誤的具體位置和原因;
服務器端校驗的缺點是,不像客戶端校驗那樣有比較好的用戶體驗,因為它直到整個表單都提交后才能返回錯誤信息;
服務器端校驗是Web應用對抗錯誤或惡意數據的最后防線,在這之后,數據將被持久化至數據庫;如今所有的服務端框架都提供了數據校驗與安全功能;
在真實的項目開發過程中,幾乎同時使用客戶端校驗與服務器端校驗的組合校驗方式,以確保數據的正確性與安全性,即兩端校驗
HTML5約束驗證API:
也稱為內置表單驗證;為了在表單提交到服務器之前驗證數據,HTML5為控件新增了一些約束驗證的功能,有了這些功能,即使Javascript被禁用或由于種種原因未能加載,也可以確保基本的驗證,但低版本的瀏覽器不支持或部分支持;
在表單提交時,如果表單元素未通過約束驗證,瀏覽器將在第一個無效表單元素上顯示錯誤消息,并且可以根據錯誤類型顯示默認消息或自定義設置的消息;
約束屬性:
required屬性:必填,任何標有required屬性的表單元素,在提交表單時都不能為空,其適用于<input>、<textarea>和<select>等元素;如:
<input type="text" name="username" required />
在Javascript中,使用對應的required屬性,如:
// 檢測瀏覽器是否支持required屬性
var isRequiredSupported="required" in document.createElement("input");
// 檢測required屬性
var isUsernameRequired=document.forms[0].elements["username"].required;
如果輸入一個空格,可以通過約束,像這種情況我們是不希望看到的,也是必須要避免的,所以此時還是需要Javascript來進行驗證,如:
document.forms[0].addEventListener("submit", function(event){
var textbox=document.forms[0].elements[0];
if(textbox.value.trim()==""){
console.log("不能為空");
event.preventDefault();
}
});
限制輸入的長度:
所有文本框都可以使用minlength和maxlength屬性來限制長度;如果輸入的字段長度小于minlength的值或大于maxlength值則無效;Javascript可以使用minLength和maxLength屬性來訪問;如:
<input type="text" id="username" name="username" required minlength="4" maxlength="6" />
<script>
var username=document.forms[0].elements["username"];
console.log(username.minLength, username.maxLength);
</script>
type屬性:增加了幾種類型,這些新類型不僅能反映數據類型的信息,而且還能提供一些默認的驗證功能;其中,”email”和”url”是得到支持最多的類型,如:
<input type="email" name="email" />
<input type="url" name="homepage" />
要檢測瀏覽器是否支持這些新類型,可以在Javascript創建一個<input>元素,然后將type屬性設置為”email”或”url”,最后再檢測這個屬性值,對于不支持它們的瀏覽器會自動將未知的值設置為“text”,而支持的瀏覽器則會返回正確的值,如:
var input=document.createElement("input");
input.type="email";
var isEmailSupported=(input.type=="email");
存在一個問題,“-@-”會被當成一個有效的郵件地址,這顯然有點不合理;
document.forms[0].addEventListener("submit", function(event){
var email=document.forms[0].elements["email"];
if(email.value !=""){
// 中文正則
// ^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$
var pattern=/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
if(!pattern.test(email.value)){
console.log("請正確輸入郵箱");
event.preventDefault();
}
}
});
如果不為新類型的<input>設置required屬性,那么空文本框也會驗證通過;另外,設置特定的輸入類型并不能阻止用戶輸入無效的值,只是應用某些默認的驗證而已;
type為”tel”的元素:
"tel" 類型的元素用于讓用戶輸入和編輯電話號碼,但瀏覽器不會自動驗證它的格式,因為世界各地的電話號碼格式差別很大,所以其在功能、表現上與“text”一致;
<input id="tel" name="tel" type="tel" required />
即使如此,但其在移動端,可能會提供為輸入電話號碼而優化的自定義鍵盤;另外,使用電話號碼的特定輸入類型也使添加自定義驗證和處理電話號碼更方便;例如,要求電話必填,用到了required屬性,并且格式是中國的手機號碼格式,如:
document.forms[0].addEventListener("submit", function(event){
var tel=document.forms[0].elements["tel"];
// 固話 :(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}
var telPattern=/^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}$/;
if(!telPattern.test(tel.value)){
console.log("電話號碼不正確");
event.preventDefault();
}
});
處理國際電話號碼的方案,如:
<form>
<p>
<label for="country">選擇國家:</label>
<select id="country" name="country">
<option value="CN" selected>中國</option>
<option value="UK">英國</option>
<option value="US">美國</option>
<option value="GER">德國</option>
</select>
</p>
<p>
<label>輸入電話號碼: </label>
<input id="areaNo" name="areaNo" type="tel" required
placeholder="區號" pattern="[0-9]{3,4}" />
<input id="number1" name="number1" type="tel" required
placeholder="號碼" pattern="[0-9]{7,8}" />
<input id="number2" name="number2" type="tel"
placeholder="分機" pattern="[0-9]*" />
</p>
<p><button>提交</button></p>
</form>
<script>
var selectElem=document.querySelector("select");
var inputElems=document.querySelectorAll("input");
selectElem.onchange=function() {
for(var i=0; i < inputElems.length; i++) {
inputElems[i].value="";
}
if(selectElem.value==="CN"){
inputElems[2].parentNode.style.display="inline";
inputElems[0].placeholder="區號";
inputElems[0].pattern="[0-9]{4}";
inputElems[1].placeholder="號碼";
inputElems[1].pattern="[0-9]{7,8}";
inputElems[2].required=false;
inputElems[2].placeholder="分機";
inputElems[2].pattern="[0-9]*";
}else if(selectElem.value==="US") {
inputElems[2].parentNode.style.display="inline";
inputElems[0].placeholder="Area code";
inputElems[0].pattern="[0-9]{3}";
inputElems[1].placeholder="First part";
inputElems[1].pattern="[0-9]{3}";
inputElems[2].required=true;
inputElems[2].placeholder="Second part";
inputElems[2].pattern="[0-9]{4}";
} else if(selectElem.value==="UK") {
inputElems[2].parentNode.style.display="none";
inputElems[0].placeholder="Area code";
inputElems[0].pattern="[0-9]{3,6}";
inputElems[1].placeholder="Local number";
inputElems[1].pattern="[0-9]{4,8}";
} else if(selectElem.value==="Ger") {
inputElems[2].parentNode.style.display="inline";
inputElems[2].required=true;
inputElems[0].placeholder="Area code";
inputElems[0].pattern="[0-9]{3,5}";
inputElems[1].placeholder="First part";
inputElems[1].pattern="[0-9]{2,4}";
inputElems[2].placeholder="Second part";
inputElems[2].pattern="[0-9]{4}";
}
}
</script>
type為“search”的元素,與“text”功能和表現基本一致,只不過其右則有個刪除號(X),所以在實際應用中,可以把它當作“text”一樣使用;
type為”color”的元素,除了IE,其他瀏覽器都支持,其調用的是系統的調色板,并且并沒有提供類型的約束驗證;
<input type="color" id="color" name="color" value="#FF0000" />
需要注意的是,其value值必須加“#”號的16進制,且完整,如“#ff0000”,也不能使用關鍵字,如“red”,并且不能調節Alpha通道;
var color=document.forms[0].elements["color"];
color.addEventListener("change", function(event){
document.body.style.backgroundColor=event.target.value;
});
各瀏覽器呈現的樣式有可能不一致,可以統一采用按鈕代替,如:
<input type="color" id="color" name="color" style="display: none;" />
<input type="button" id="btnColor" name="btnColor" value="調色板" />
<input type="text" id="txtColor" name="txtColor" placeholder="#FFFFFF" />
<script>
var btnColor=document.getElementById("btnColor");
btnColor.addEventListener("click", function(event){
var color=document.getElementById("color");
color.click();
color.addEventListener("change", function(event){
document.getElementById("txtColor").value=this.value;
});
},false);
</script>
數值范圍:
HTML5還定義了其他幾個輸入元素,這些元素都要求填寫某種基于數字的值,如:”number”、”range”、”datetime”、”datetime-local”、”date”、”month”、”week”和”time”;瀏覽器對這些類型的支持并不友好;
對于所有這些數值類型的輸入元素,可以指定min、max和step屬性(步長值或差值),如:
<input type="number" min="20" max="100" step="5" name="age" />
檢測瀏覽器是否支持,方法同上;
在Javascript中,以上屬性都有相對應的同名屬性,另外,還存在兩個方法:stepUp()和stepDown(),都接收一個可選的參數:在當前值的基礎上加上或減去的step倍數的數值(默認加減1),如:
var age=document.forms[0].elements["age"];
age.stepUp(); // 增加5,因為step為5
age.stepUp(10); // 增加50,為step的10倍
age.stepDown(); // 減少5
age.stepDown(3); // 減少step的3倍,15
IE在輸入非數字的情況下也可以通過約束,因此,需要使用Javascript判斷驗證,如:
var age=document.forms[0].elements["age"];
age.addEventListener("keypress", function(event){
var charCode=event.charCode;
if(!/\d/.test(String.fromCharCode(charCode)))
event.preventDefault();
});
type為range的元素,IE9不支持,并且在各瀏覽器中呈現的樣式并不一致;
<input type="range" max="50" min="10" step="2" value="30" />
其擁有屬性:
var range=document.querySelector('input[type="range"]');
console.log(range.max);
console.log(range.min);
console.log(range.step);
console.log(range.value);
console.log(range.defaultValue);
type為”date”、”datetime”、”datetime-local”、”month”、”week”和”time”,IE不支持,所有瀏覽器不支持”datetime”,Firefox只支持”date”和”time”;各瀏覽器呈現的也不一致;所以目前在所有應用中,并不會使用這些表單元素;對于不支持的表單元素,瀏覽器直接解析為type為“text”元素;
pattern屬性:輸入模式
該屬性也是HTML5新增的,其值是一個正則表達式,用于匹配文本框中的值;、
<input type="text" name="age" pattern="\d+" />
<!-- 限制為4-8個字符,并要求它只包含小寫字母 -->
<input type="text" id="username" name="username" pattern="[a-z]{4,8}" required />
<!-- 包含大小寫字母和數字的組合,長度在8-10之間 -->
<input type="password" id="pwd" name="pwd" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}" />
注,模式的開頭和末尾不用加^和$;
在Javascript中,通過同名的pattern屬性來訪問模式,如:
var pattern=document.forms[0].elements[0].pattern;
// 檢測是否支持
var isPatternSupported="pattern" in document.createElement("input");
// 身份證號
var id=document.getElementById("id");
id.pattern="([0-9]){17}(\\d|x|X)";
注:<textarea>不支持pattern屬性;
有一些<input>元素類型不需要pattern屬性進行校驗,例如”email”和”url”類型,因為它們本身就具有類型格式的校驗;即使如此,也可以同時使用pattern屬性,可以更加詳細和靈活的定制約束規則;
檢測有效性:
使用表單元素的checkValidity()方法可以檢測該元素的值是否有效,如果其值有效,該方法返回true,否則返回false;
其判斷是否有效的依據就是以上所講的約束;如:
<input type="text" id="username" name="username" pattern="[a-z]{4,8}" required />
<p><input type="button" id="btn" name="btn" value="按鈕" /></p>
<script>
var btn=document.getElementById("btn");
btn.addEventListener("click", function(event){
var username=document.getElementById("username");
console.log(username.checkValidity());
if(username.checkValidity()){
console.log("約束通過");
}else{
console.log("不通過");
}
},false);
</script>
要檢測整個表單是否有效,可以在表單自身上調用checkValidity()方法;如果所有表單控件都有效,該方法返回true,即使其中一個表單無效,該方法都會返回false,如:
btn.addEventListener("click", function(event){
if(document.forms[0].checkValidity()){
console.log("約束通過");
}else{
console.log("不通過");
}
},false);
validity屬性:
checkValidity()方法只會返回是否有效的結果,但表單元素的validity屬性則會返回有效或無效的原因,該屬性是一個ValidityState類型的對象:
btn.onclick=function(){
var num=document.forms[0].elements["num"];
console.log(num.validity); // ValidityState
}
其包含一系列屬性,每個屬性會返回一個布爾值:
對于這些布爾屬性中的每一個,值為true就表示驗證失敗;如果出現失敗,瀏覽器將提醒用戶并阻止提交表單;如果驗證成功,即其他屬性均返回false,則valid將為true,就可以提交表單;
因此,要想得到更具體的信息,就應該使用validity屬性來檢測表單元素的有效性,如:
<p><input type="email" name="email" id="email" required pattern="[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+" maxlength="10" /></p>
<p><input type="button" id="btn" name="btn" value="按鈕" /></p>
</form>
<script>
var btn=document.getElementById("btn");
btn.addEventListener("click", function(event){
var email=document.getElementById("email");
if(email.validity && !email.validity.valid){
if(email.validity.valueMissing)
console.log("請輸入數據");
else if(email.validity.typeMismatch)
console.log("請輸入郵件地址");
else if(email.validity.tooLong)
console.log("超出長度");
else if(email.validity.patternMismatch)
console.log("地址中不能包括特殊字符");
else
console.log("啥玩意啊");
}
},false);
</script>
自定義錯誤信息:
主要使用validationMessage屬性和setCustomValidity()方法;如果沒有通過驗證,瀏覽器會有默認地提示信息,該信息保存在表單元素的validationMessage屬性中,如:
var email=document.forms[0].elements["email"];
console.log(email.validationMessage); // 如果有required特性,提示"請填寫此字段"
var btn=document.getElementById("btn");
btn.addEventListener("click", function(event){
var email=document.getElementById("email");
// 根據不同的驗證失敗的原因,提示各自默認的信息
if(email.validity && !email.validity.valid){
if(email.validity.valueMissing)
console.log(email.validationMessage); // 請填寫此字段
else if(email.validity.typeMismatch)
// 請在電子郵件地址中包括“@”。“a”中缺少“@”。
console.log(email.validationMessage);
else if(email.validity.tooLong)
console.log(email.validationMessage);
else if(email.validity.patternMismatch)
// 請與所請求的格式保持一致。
console.log(email.validationMessage);
else
console.log(email.validationMessage);
}
// 或者
// if(email.validity && !email.validity.valid){
// console.log(email.validationMessage);
// }
},false);
但是該屬性是只讀的,如果想修改這個值,可以調用setCustomValidity()改變validationMessage的值;如:
var email=document.forms[0].elements["email"];
email.setCustomValidity("不要懶,必須填!");
email.validationMessage='這個字段必須填上。';
console.log(email.validationMessage);
現在再單擊提交,如果沒有驗證通過,會提示自定義的消息;
如果將自定義錯誤設置為truthy值,則將阻止提交表單;因為調用了setCustomValidity()方法,所以validity的customError屬性為true,導致validy屬性為false,所以提交不了;
var btnsubmit=document.querySelector('input[type="submit"]');
btnsubmit.addEventListener("click", function(event){
console.log(email.validationMessage);
console.log(email.checkValidity()); // false
// customError: true, valueMissing: true, valid: false
console.log(email.validity);
});
只有將自定義消息設置為空才能提交表單,而將自定義消息設置為空,也就是將消息恢復為瀏覽器默認的消息,如:
btnsubmit.addEventListener("click", function(event){
if (email.value !="") {
email.setCustomValidity("");
}
console.log(email.validationMessage); // 默認的消息,地址包含@
console.log(email.checkValidity()); // false
// typeMismatch:true, valid: false
console.log(email.validity);
});
如果此時沒有下一個約束,或者其他驗證均有效的話,就可以順利得交了;
當然,這些代碼放到一個普通按鈕的click事件處理程序中也是可以的,如:
var btn=document.getElementById("btn");
btn.addEventListener("click", function(event){
if (email.value !="") {
email.setCustomValidity("");
}
console.log(email.validationMessage);
console.log(email.checkValidity());
console.log(email.validity);
if (!email.checkValidity()) {
console.log(email.validationMessage);
}else{
document.forms[0].submit();
}
});
可以根據不同的約束驗證失敗時分別自定義提示消息,如:
function validate(input) {
var validityState=input.validity;
if(validityState.valueMissing){
input.setCustomValidity('必填');
}else if(validityState.typeMismatch){
input.setCustomValidity('類型不正確');
}else if(validityState.rangeUnderflow) {
input.setCustomValidity('值太小');
}else if(validityState.rangeOverflow) {
input.setCustomValidity('值太大');
}else if(validityState.stepMisMatch){
input.setCustomValidity('步長值不合理');
}else if(validityState.tooLong){
input.setCustomValidity('長度超出了maxLength');
}else if(validityState.tooShort){
input.setCustomValidity('長度小于minLength');
}else if(validityState.patternMismatch){
input.setCustomValidity("格式不正確");
}else if(validityState.badInput){
input.setCustomValidity('值類型無法轉換');
} else {
input.setCustomValidity('');
}
return validityState.valid;
}
// 應用
var btnsubmit=document.querySelector('input[type="submit"]');
btnsubmit.addEventListener("click", function(event){
var email=document.getElementById("email");
if(!validate(email)){
console.log(email.validationMessage);
console.log(email.checkValidity());
console.log(email.validity);
}
});
// 或者普通按鈕
var btn=document.getElementById("btn");
btn.addEventListener("click", function(event){
var email=document.getElementById("email");
if(!validate(email)){
console.log(email.validationMessage);
console.log(email.checkValidity());
console.log(email.validity);
}else{
document.forms[0].submit();
}
});
也可以配合正則表達式,設備自定義錯誤消息,如:
<form>
<label for="ZIP">郵編:</label>
<input type="text" id="ZIP">
<label for="Country">國家:</label>
<select id="Country">
<option value="cn">中國</option>
<option value="ch">瑞士</option>
<option value="fr">法國</option>
<option value="de">德國</option>
<option value="nl">荷蘭</option>
</select>
<input type="submit" value="Validate">
</form>
<script>
function checkZIP() {
// 定義每個國家對應的,郵政編碼必須遵循的模式及消息
var constraints={
cn : [ '^(CN-)?\\d{5}$', "中國郵編需要5個數字:例如CN-10022或10022"],
ch : [ '^(CH-)?\\d{4}$', "瑞士郵編需要4個數字:例如CH-1950或1950" ],
fr : [ '^(F-)?\\d{5}$' , "法國郵編需要5個數字:例如F-75012或75012" ],
de : [ '^(D-)?\\d{5}$' , "德國郵編需要5個數字:例如D-12345或12345" ],
nl : [ '^(NL-)?\\d{4}\\s*([A-RT-Z][A-Z]|S[BCE-RT-Z])$',
"荷蘭郵編需要4位數字,后跟除SA、SD和SS之外的2個字母" ]
};
var country=document.getElementById("Country").value;
var ZIPField=document.getElementById("ZIP");
// 創建正則對象
var constraint=new RegExp(constraints[country][0], "");
console.log(constraint);
// 檢測
if(constraint.test(ZIPField.value)) {
// 通過約束校驗
ZIPField.setCustomValidity("");
}else{
// 沒有通過約束校驗,設置當前國家的錯誤消息
ZIPField.setCustomValidity(constraints[country][1]);
}
}
window.onload=function () {
document.getElementById("Country").onchange=checkZIP;
document.getElementById("ZIP").oninput=checkZIP;
}
</script>
novalidate屬性和formnovalidate屬性:
禁用驗證,可以設置表單不進行驗證;
<form name="myform" novalidate ></form>
在Javascript中使用noValidate屬性可以獲取或設置這個值,如果這個屬性存在,值為true,否則為false;
document.forms[0].noValidate=true; // 禁用驗證
如果一個表單中有多個提交按鈕,為了指定點擊某個提交按鈕不必驗證表單,可以在相應的按鈕上添加formnovalidate屬性,如:
<form name="myform">
<input type="submit" value="驗證提交" />
<input type="submit" formnovalidate value="不驗證提交" />
</form>
使用Javascript也可以設置這個屬性:
document.forms[0].elements["btnNoValidate"].formNoValidate=true;
一般情況下,表單使用novalidate屬性關閉瀏覽器的自動校驗的目的,就是使用腳本控制表單的校驗;但是,這并不會禁止對約束校驗的支持或對約束CSS偽類的支持;如:
<style>
input:invalid{border-color: #900; background-color: #FDD;}
input:focus:invalid{outline: none;}
.error {color: white; background-color: lightgreen; padding: 0.1em 0.2em;}
.error.active {background-color: red;}
</style>
<form novalidate>
<p>郵箱地址:<input type="email" id="mail" name="mail" required />
<span class="error">如:a@a.com</span></p>
<button>提交</button>
</form>
<script>
var form=document.getElementsByTagName('form')[0];
var email=document.getElementById('mail');
var error=document.querySelector('.error');
email.addEventListener("input", function (event) {
if (email.validity.valid) {
error.innerHTML="正確";
error.className="error";
}
}, false);
form.addEventListener("submit", function (event) {
if(!email.validity.valid){
error.innerHTML="期望一個正確郵箱地址";
error.className="error active";
event.preventDefault();
}
}, false);
</script>
invalid事件:
當表單提交時,若任一個表單元素在檢查有效性時,不符合對它的約束條件,則會觸發invalid事件;對元素有效性的檢查是在提交表單之前或調用表單或表單元素自己的checkValidity()方法之后;
<form>
輸入1-10之間的整數:<input type="number" min="1" max="10" required /><br/>
<input type="submit" value="提交" />
<input type="button" id="btn" name="btn" value="按鈕" />
</form>
<p id="log">錯誤:</p>
<script>
var input=document.querySelector('input[type="number"]');
var log=document.getElementById("log");
// 當提交表單時觸發
input.addEventListener("invalid", function(event){
log.textContent +=event.target.validationMessage;
});
// 調用checkValidity()也會觸發
var btn=document.getElementById("btn");
btn.addEventListener("click", function(event){
console.log(input.validity);
input.checkValidity(); // 觸發invalid事件
});
</script>
在也可以invalid事件中自定義錯誤消息,如:
<form>
輸入大小寫字母:<input type="text" name="username" id="username" required pattern="[A-Za-z]+">
<input type="submit" value="提交" />
<input type="button" id="btn" name="btn" value="按鈕" />
</form>
<script>
var username=document.querySelector('#username');
username.addEventListener('input', function(e){
// 如果一開始沒有驗證通過,必須在此設為空字符串,否則即使有效也無法提交
username.setCustomValidity('');
username.checkValidity();
});
// 提交時觸發
username.addEventListener('invalid', function(e){
// if(username.value==='') {
// username.setCustomValidity('請輸入用戶名');
// } else {
// username.setCustomValidity('用戶名只能包含大寫和小寫字母');
// }
// 或者
if(username.validity.valueMissing) {
username.setCustomValidity('請輸入用戶名');
}else if(username.validity.patternMismatch){
username.setCustomValidity('用戶名只能包含大寫和小寫字母');
}
});
// 調用checkValidity()觸發
var btn=document.getElementById("btn");
btn.addEventListener("click", function(event){
console.log(username.validity);
if(!username.checkValidity()){ // 觸發invalid事件
console.log(username.validationMessage);
}else{
document.forms[0].submit();
}
});
</script>
:valid和:invalid偽類:
:valid CSS偽類表示表單或表單元素數據驗證通過的樣式;
:invalid CSS偽類表示表單或表單元素未通過驗證樣式;
這兩個偽類能簡單地將校驗字段展示為一種能讓用戶辨別出其輸入數據的正確與否的樣式;
<style>
form:invalid {
border: 5px solid #ffdddd;
}
form:valid {
border: 5px solid #ddffdd;
}
input:valid {
background-color: powderblue;
}
input:invalid{
background-color: pink;
}
</style>
如:驗證電話號碼:
<style>
div {margin-bottom: 10px; position: relative;}
input[type="tel"] {width: 100px;}
input + span {padding-right: 30px;}
input:invalid+span:after {
position: absolute; content: '?';
padding-left: 5px; color: #8b0000;
}
input:valid+span:after {
position: absolute;
content: '?'; padding-left: 5px; color: #009000;
}
</style>
<div>
<label for="tel">電話號碼(必填): </label>
<input id="tel" name="tel" type="tel" required>
<span class="validity"></span>
</div>
:required偽類和:optional偽類:
:required CSS偽類表示任意設置了required屬性的<input>、<select>或<textarea>元素;這個偽類對于高亮顯示在提交表單之前必須具有有效數據的字段非常有用;
:optional CSS偽類表示任意沒有required屬性的<input>、<select>或<textarea>元素使用它;
input:required{
border: 1px solid green;
}
input:optional {
border: 1px dashed black;
}
:in-range偽類和:out-of-range偽類:使用方式同上;
不使用內置表單校驗API:
對于老舊瀏覽器并不支持HTML的約束校驗,因此只能使用JavaScript來校驗表單數據,如:
<style>
input.invalid{border-color: #900; background-color: #FDD;}
input:focus.invalid{outline: none;}
.error {color: white; background-color: lightgreen; padding: 0.1em 0.2em;}
.error.active {background-color: red;}
</style>
<form>
<p>郵箱地址:<input type="text" class="mail" id="mail" name="mail">
<span class="error">如:a@a.com</span><p>
<button type="submit">提交</button>
</form>
<script>
var form=document.getElementsByTagName('form')[0];
var email=document.getElementById('mail');
var error=email;
while ((error=error.nextSibling).nodeType !=1);
var emailRegExp=/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
function addEvent(element, event, callback) {
element["on" + event]=function (e) {
var output=callback(e);
if (output===false)
return false;
};
};
addEvent(window, "load", function () {
var test=email.value.length===0 || emailRegExp.test(email.value);
email.className=test ? "valid" : "invalid";
});
addEvent(email, "input", function () {
var test=email.value.length===0 || emailRegExp.test(email.value);
if(test){
email.className="valid";
error.innerHTML="正確";
error.className="error";
} else {
email.className="invalid";
}
});
addEvent(form, "submit", function () {
var test=email.value.length !==0 || emailRegExp.test(email.value);
console.log(test);
if(!test){
email.className="invalid";
error.innerHTML="需要一個正確的郵箱地址";
error.className="error active";
return false;
}else{
email.className="valid";
error.innerHTML="正確";
error.className="error";
}
});
</script>
遠程校驗:
當用戶輸入的數據與存儲在應用程序服務器端的附加數據綁定時,這種校驗是必要的,一般采用Ajax異步請求進行校驗;
篇介紹了表單的使用,表單有很多控件,比如輸入框,密碼框、文本域,按鈕等。按類型可分如下:
此類控件有很多種類型,使用<input type="類型">語法,常見類型如下:
type 值 | 含義 |
text | 文字字段 |
password | 密碼域,用戶看不到明文,以*代替 |
radio | 單選按鈕 |
checkbox | 多選按鈕 |
button | 普通按鈕 |
submit | 提交按鈕 |
reset | 重置按鈕 |
image | 圖像域,用圖像作為背景的提交按鈕 |
hidden | 隱藏域,不可見的輸入框 |
file | 文本域,用于上傳文件等非文本數據 |
文本輸入框和密碼框
除了顯示形式不一樣,其它屬性一樣,有以下屬性:
如下是文本輸入框和密碼框制作一個登錄表單
html代碼:
<!DOCTYPE html>
<html>
<body>
<h1>用戶登錄</h1>
<form action="/demo/html/action_page.php">
<label for="fname">用戶名:</label><br>
<input type="text" id="username" name="username" value=""><br>
<label for="lname">密碼:</label><br>
<input type="password" id="pwsd" name="pwsd" value=""><br><br>
<input type="submit" value="提交">
</form>
</body>
</html>
顯示效果:
HTML5 輸入類型
除了以上幾種類型,HTML5 還增加了多個新的輸入類型:
如下代碼:
<!DOCTYPE html>
<html>
<body>
<form action="/demo/demo_form.asp">
數字類型(1 到 5 之間):
<input type="number" name="quantity" min="1" max="5">
IE9 及早期版本不支持 type="number"。<br>
color 選擇顏色:
<input type="color" name="color"><br>
生日:
<input type="date" name="bday"><br>
年月:
<input type="month" name="bdaymonth"><br>
年周:
<input type="week" name="week_year"><br>
時間:
<input type="time" name="usr_time"><br>
一定范圍
<input type="range" name="points" min="0" max="10"><br>
E-mail:
<input type="email" name="email">
能夠在被提交時自動對電子郵件地址進行驗證<br>
搜索:
<input type="search" name="googlesearch"><br>
電話:
<input type="tel" name="usrtel">
目前只有 Safari 8 支持 tel 類型。<br>
url:
<input type="url" name="url">
提交時能夠自動驗證 url 字段<br>
<input type="submit">
</form>
</body>
</html>
效果如下:
單選和多選按鈕
使用 type=“radio” 和 type=“checkbox” 定義是單選還是多選,除了name和value屬性外,單選和多選都有一個 checked屬性定義默認選擇的項,checked=“true”指選中那個選項,表單會將 checked=“true” 的選型值傳遞給后臺。
如下實例:
<!DOCTYPE html>
<html>
<body>
<h4>單選和多選</h4>
<form action="/demo/demo_form.asp">
水果:
<input type="radio" name="shuiguo" value="banner" checked> 香蕉
<input type="radio" name="shuiguo" value="apple"> 蘋果
<br><br>
省份:
<input type="checkbox" name="shengfen" value="shannxi" checked> 陜西
<input type="checkbox" name="shengfen" value="sanxi"> 山西
<input type="checkbox" name="shengfen" value="gdong"> 廣東
<br><br>
<input type="submit">
</form>
</body>
</html>
顯示效果:
單選和多選傳遞給后臺的數據是不一樣的,如下會看到地址欄中的數據,多選會發送多個值,后臺將會獲取一個數組形式的數據。
/demo/demo_form.asp?shuiguo=banner&shengfen=shannxi&shengfen=sanxi
普通按鈕、提交按鈕、重置按鈕
普通按鈕:type=“button”,一般配合腳本使用,語法如下:
<input type="button" name="名稱" value="按鈕值" onclick="腳本程序" />
value 值就是按鈕在頁面顯示的文字,onclick屬性定義了腳本事件,這里指單擊按鈕時所進行的處理。
如下示例:
<!DOCTYPE html>
<html>
<body>
<form>
<input type="button" value="普通按鈕">
<input type="button" value="打開窗口" onclick="window.open()">
<input type="button" value="您好" onclick="alert('您好')">
</form>
</body>
</html>
單擊您好按鈕
提交按鈕:type=“submit”,用于提交表單內容,是一種特殊按鈕。
如剛才的登錄表單,提交后會返回結果:
重置按鈕:type="reset",用于清除表單數據,也是一種特殊按鈕。
輸入數據
點擊重置按鈕后,表單數據清空
重置清空數據
HTML5 按鈕
除了使用input定義按鈕,還可以使用 html5 新增的<button> 標簽定義按鈕,button 使用語法如下:
<form action="/demo/html/action_page.php">
<button type="button">普通按鈕</button>
<button type="submit">提交按鈕</button>
</form>
其它輸入類控件
隱藏域 —— hidden
文件域 —— file
如下示例:
<form action="/demo/html/action_page.php">
<label for="fname">隱藏域:</label>
<input type="hidden" id="hidden" name="hidden" value=""><br>
<label for="lname">文件域:</label>
<input type="file" id="file" name="file" value=""><br>
<input type="submit" value="提交">
</form>
顯示效果
可以看到,隱藏域在頁面中不顯示,單擊文件域選擇文件按鈕可以選擇文件,比如word文件,電子表格文件等,會以非文本方式傳送到后臺的,常用來實現文件上傳功能。
除了input 類型的控件,還有文本域 textarea ,一種特殊的文本框,它與input 文本輸入框的區別就是可以輸入多行文字,input 文本輸入框是單行的無法輸入多行文字。
如下示例:
<p>textarea 元素定義多行輸入字段。</p>
<form action="/demo/html/action_page.php">
<textarea name="message" rows="10" cols="30">The cat was playing in the garden.</textarea>
<br><br>
<input type="submit">
</form>
效果如下:
rows 屬性定義文本域的高度是幾行,cols 定義文本域寬度占幾列,比如上面定義了高10行寬30列的文本域。
下拉菜單作用和單選按鈕類似,只不過它更加節省空間,當要選擇的選型很多時,就不適合使用radio空間,所以當選項很多的時候,使用下拉菜單,語法如下:
<select name="名稱">
<option value="選項值1" selected>選項1</option>
<option value="選項值2">選項3</option>
更多option......
</select>
多選列表和多選按鈕類似,一樣為了節省空間,當數據選項比較多時,使用多選列表,語法如下:
<select name="名稱" size="可看見的列表項數" multiple>
<option value="選項值1" selected>選項1</option>
<option value="選項值2">選項3</option>
更多option......
</select>
多選比下拉菜單不同之處是多了一個multiple屬性,定義多選的,且表現形式也不一樣,不是下拉而是一個列表。
如下代碼:
<!DOCTYPE html>
<html>
<body>
<form action="/demo/demo_form.asp">
下拉菜單:<br>
<select name="cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="fiat">Fiat</option>
<option value="audi">Audi</option>
</select>
<br>
多選列表:<br>
<select name="cars" size="3" multiple>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="fiat">Fiat</option>
<option value="audi">Audi</option>
</select>
<br><br>
<input type="submit">
</form>
</body>
</html>
顯示效果:
這里需要注意的是,多選列表多選時需要按住ctrl鍵同時鼠標單擊選擇才能多選,效果如下:
到這里,已介紹了大部分的表單控件,現在你可以使用他們制作自己的表單,表單通常在動態網站中使用,這為以后制作動態網站打下基礎。
還有許多屬性沒有講到,比如html5新增的一些屬性和功能,可自行參考 w3cshool 等網站學習,感謝關注,學習愉快!
上篇 : 前端入門——html 表單
下篇: 前端入門 —— 網頁中使用窗口框架
*請認真填寫需求信息,我們會在24小時內與您取得聯系。