整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

好程序员web前端教程分享JavaScript如何实

好程序员web前端教程分享JavaScript如何实现表单验证

 好程序员web前端教程分享web开发中JavaScript如何实现表单验证,希望对用到的同学能有所帮助!

JS 错误

DOM 简介

JavaScript 可用来在数据被送往服务器前对 HTML 表单中的这些输入数据进行验证。

JavaScript 表单验证

JavaScript 可用来在数据被送往服务器前对 HTML 表单中的这些输入数据进行验证。

被 JavaScript 验证的这些典型的表单数据有:

用户是否已填写表单中的必填项目?

用户输入的邮件地址是否合法?

用户是否已输入合法的日期?

用户是否在数据域 (numeric field) 中输入了文本?

必填(或必选)项目

下面的函数用来检查用户是否已填写表单中的必填(或必选)项目。假如必填或必选项为空,那么警告框会弹出,并且函数的返回值为 false,否则函数的返回值则为 true(意味着数据没有问题):

function validate_required(field,alerttxt)

{

with (field)

{

if (value==null||value=="")

{alert(alerttxt);return false}

else {return true}

}

}

下面是连同 HTML 表单的代码:

<html>

<head>

<script type="text/javascript">

function validate_required(field,alerttxt)

{

with (field)

{

if (value==null||value=="")

{alert(alerttxt);return false}

else {return true}

}

}

function validate_form(thisform)

{

with (thisform)

{

if (validate_required(email,"Email must be filled out!")==false)

{email.focus();return false}

}

}

</script>

</head>

<body>

<form action="submitpage.htm" onsubmit="return validate_form(this)" method="post">

Email: <input type="text" name="email" size="30">

<input type="submit" value="Submit">

</form>

</body>

</html>

内容是《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" />

其拥有属性:

  • max:设置或返回滑块控件的最大值;
  • min:设置或返回滑块控件的最小值;
  • step:设置或返回每次拖动滑块控件时的递增量;
  • value:设置或返回滑块控件的 value 属性值;
  • defaultValue:设置或返回滑块控件的默认值;
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
}

其包含一系列属性,每个属性会返回一个布尔值:

  • patternMismatch:如果值与指定的pattern属性不匹配,返回true;
  • rangeOverflow:如果值比max值大,返回true;
  • rangeUnderflow:如果值比min值小,返回true;
  • stepMisMatch:如果step步长值不合理,返回true,step=“any”永远不会抛出此错误;
  • tooLong:如果值的长度超过了maxlength属性指定的长度,返回true;有的浏览器会自动约束字符数量,因此这个值可能永远都返回false;
  • tooShort:如果值的长度低于minlength属性指定的长度,返回true;
  • typeMismatch:如果值不是”email”或”url”等要求的格式,返回true;
  • valueMissing:如果标注为required的元素中没有值,返回true;
  • badInput:如果浏览器无法转换用户的输入,返回true;例如,number类型的输入元素,但其内容是字符串;
  • customError:如果设置了setCustomValidity(),则为true,否则为false;
  • valid:如果这里的其他属性都是false;checkValidity()方法也要求相同的值;

对于这些布尔属性中的每一个,值为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异步请求进行校验;

html5 中,在增加了大量的表单元素与属性的同时,也增加了大量在提交时对表单与表单内新增元素进行内容有效性验证的功能,接下来我们来说1下自动验证。

在html5中,通过对元素使用属性的方法,可以实现在表单提交时履行自动验证的功能,在履行代码后,将在表单提交时自动验证输入的内容是不是为数字,如果验证通不过,将显示毛病信息文字。


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF⑻">
    <title>表单验证示例</title>
</head>
<body>
    <form action="#" method="post">
            <input type="text" name="text" required pattern="^\w.*$">
            <input type="submit" value="提交">
    </form>
</body>
</html>

接下来我们来看1下在html5 中追加的关于对元素内输入内容进行限制的属性的指定。

1.required属性

html5 中新增的required属性可以利用在大多数输入元素上(除隐藏元素,图片元素按钮上)。在提交时,如果元素中内容为空白。则不允许提交,同时在阅读器中显示信息提示文字,提示用户这个元素中必须输入内容,效果如图

2.pattern属性之条件到的新增的input元素,比如email,number,URL等,要求输入内容符合1定的格式,对input元素使用pattern属性,并且将属性值设置为某个格式的正则表达式,在提交时会检查其内容是不是符合给定格式。当输入的内容不符合给定格式时,则不允许提交,同时在阅读器中显示信息提示文字,提交输入的内容必须符合给定格式,代码以下,要求输入内容为1个数字与3个大写字母:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF⑻">
    <title>表单验证示例</title>
</head>
<body>
    <form action="#" method="post">
            请输入指定内容:<input pattern="[0⑼][A-Z]{3}" name="part" placeholder="输入:1个数字3个大写字母">
            <input type="submit" value="提交">
    </form>
</body>
</html>

履行效果以下:

3.min属性与max属性

min与max这两个属性是日期类型或数值类型的input元素的专用属性,他们限制了在input元素中输入的数值与日期的范围。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF⑻">
    <title>表单验证示例</title>
</head>
<body>
    <form action="#" method="post">
            请输入数值:<input type="number" name="point" min="0" max="100" />
            <input type="submit" value="提交">
    </form>
</body>
</html>

履行效果以下:

4.step属性

step属性控制input元素中的值增加过减少时的步骤。例如当你想让用户输入的值在0与100之间,但必须是5的倍数时,你可以指定step为5,代码以下:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF⑻">
    <title>表单验证示例</title>
</head>
<body>
    <form action="#" method="get">
      <input type="number" name="point" step="5" />
      <input type="submit" />
    </form>
</body>
</html>

效果以下:


原文:http://www.wfuyu.com/htmlcss/27520.html