HTML5 表单验证

0x01 概述

  • 表单验证的两种方式:

    1. form 表单提交到后台
    2. 无刷新页面的 ajax 提交

    以下内容主要为 form 表单验证

  • HTML5 表单基本特性与新特性:

    1. placeholder:输入框中的灰色文字提示

      <input placeholder="Enter username" />
      
    2. type:HTML5 新增类型

      color、date、email、number、range、search、tel、url 等

      <input type="color" />
      
    3. datalist:下拉框选择提示

      <input list="myList" />
      <datalist id="myList">
        <option value="1">Alex</option>
        <option value="2">Alice</option>
        <option value="3">Bob</option>
      </datalist>
      
    4. autocomplete:自动输入补全提示

      <input autocomplete="off" />
      
    5. autofocus:初始化页面后自动获取焦点

      <input autofocus />
      
    6. required:设置表单元素必填

      <input required />
      
      • 对于必填项,设置提交表单时做到不验证

        <form novalidate></form>
        

        <button formnovalidate></button>
        
    7. pattern:使用正则验证

      <input pattern="/^\d+$/" />
      

0x02 约束验证 API

  • HTML5 的约束验证 API 包括:

    1. willValidate:验证元素约束是否被符合
    2. validity:本质上是 validate state 对象,表示元素当前所处的验证状态
    3. validationMessage:描述与元素相关约束的失败信息
    4. checkValidity():判断元素是否满足任意约束
    5. setCustomValidity():设置自定义验证信息
  • validity 属性

    1. 表单与 JS

      <body>
        <form action="" method="POST">
          <input
            type="text"
            name="username"
            id="username"
            placeholder="Enter your username"
            required="required"
            pattern="^\d{4}$"
            autofocus
          />
          <input type="submit" value="Submit" />
        </form>
        <script type="text/javascript">
          let input = document.getElementById("username");
          console.log(input.validity);
          console.log(username.validity);
        </script>
      </body>
      
    2. 输出结果

      ValidityState {
          badInput: false
          customError: false
          patternMismatch: false
      	rangeOverflow: false
      	rangeUnderflow: false
      	stepMismatch: false
      	tooLong: false
      	tooShort: false
      	typeMismatch: false
      	valid: false
      	valueMissing: true
      }
      
      • badInput:用户是否提供了一个浏览器无法转换的输入
      • customError:setCustomValidity()
      • patternMismatch:pattern,正则是否匹配
      • rangeOverflow:max,是否超过最大时
      • rangeUnderflow:min,是否小于最小值
      • stepMismatch:step,步长是否匹配
      • tooLong:maxlength,是否过长
      • tooShort:minlength,是否过短
      • typeMismatch:类型是否匹配
      • valueMissing:required,数据是否必填
  • checkValidity() 方法

    • 如果元素没有满足该方法的任意约束,则返回 false
  • setCustomValidity() 方法

    • 设置自定义验证信息,用于即将实施与验证的约束来覆盖预定义的信息
    <body>
      <form action="" method="POST">
        <input type="text" id="username" value="" pattern="^\d{2}" oninput="checkit(this)" />
        <input type="submit" value="Submit" />
      </form>
      <script type="text/javascript">
        function checkit(obj) {
          const it = obj.validity
          if (it.valueMissing) {
            obj.setCustomValidity("注意,此项不能为空")
            obj.reportValidity()
          } else if (it.patternMismatch) {
            obj.setCustomValidity("请输入两位数字")
            obj.reportValidity()
          } else {
            obj.setCustomValidity("")
          }
        }
      </script>
    </body>
    

0x03 验证美化

(1)伪类

  1. :required:optional

    <head>
      <meta charset="UTF-8" />
      <style>
        input:required {
          background-color: #ff7777;
        }
    
        input:optional {
          background-color: #77ff77;
        }
    
        input[type="submit"] {
          background-color: white;
        }
      </style>
    </head>
    
    <body>
      <form action="" method="POST">
        <input type="text" required />
        <input type="text" pattern="^\d{6}" />
        <input type="submit" value="Submit" />
      </form>
    </body>
    
  2. :in-range:out-of-range

    <head>
      <meta charset="UTF-8" />
      <style>
        input:in-range {
          background-color: #ff7777;
        }
    
        input:out-of-range {
          background-color: #77ff77;
        }
    
        input[type="submit"] {
          background-color: white;
        }
      </style>
    </head>
    
    <body>
      <form action="" method="POST">
        <input type="number" min="5" max="10" />
        <input type="submit" value="Submit" />
      </form>
    </body>
    
  3. :valid:invalid

    <head>
      <meta charset="UTF-8" />
      <style>
        input:valid {
          background-color: #ff7777;
        }
    
        input:invalid {
          background-color: #77ff77;
        }
    
        input[type="submit"] {
          background-color: white;
        }
      </style>
    </head>
    
    <body>
      <form action="" method="POST">
        <input type="text" required />
        <input type="text" pattern="^\d{6}" />
        <input type="submit" value="Submit" />
      </form>
    </body>
    
  4. :read-only:read-write

    <head>
      <meta charset="UTF-8" />
      <style>
        input:read-only {
          background-color: #ff7777;
        }
    
        input:read-write {
          background-color: #77ff77;
        }
    
        input[type="submit"] {
          background-color: white;
        }
      </style>
    </head>
    
    <body>
      <form action="" method="POST">
        <input type="text" readonly />
        <input type="text" />
        <input type="submit" value="Submit" />
      </form>
    </body>
    

(2)事件

  1. oninput 事件
  2. oninvalid 事件
  3. onchange 事件

(3)自定义提示气泡

<body>
  <form action="" method="POST">
    <input type="tel" required />
    <input type="submit" value="Submit" id="submit" />
  </form>
  <script type="text/javascript">
    const form = document.querySelector("form");
    form.addEventListener("invalid", (e) => e.preventDefault(), true);
    form.addEventListener(
      "submit",
      (e) => {
        if (!this.checkValidity()) e.preventDefault();
      },
      true
    );
    document.getElementById("submit").addEventListener("click", () => {
      const errorMessages = document.querySelectorAll(".error-message");
      errorMessages.forEach((item) => item.parentNode.removeChild(item));
      const inVaildityFields = document.querySelectorAll(":invalid");
      inVaildityFields.forEach((item) =>
        item.parentNode.insertAdjacentHTML(
          "beforeend",
          `<div class="error-message">${item.validationMessage}</div>`
        )
      );
      if (inVaildityFields.length > 0) inVaildityFields[0].focus();
    })
  </script>
</body>

-End-

posted @ 2024-07-24 14:50  SRIGT  阅读(45)  评论(0编辑  收藏  举报