亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

全部開發者教程

JavaScript 入門教程

表單校驗

本篇主要介紹使用 JavaScript 進行表單驗證。

表單驗證并不是 JavaScript 提供的某種特性,而是結合各種特性達到的一種目的,是需求的產物。

所有線上產品的表單幾乎都有驗證,如注冊時要求“用戶名 6-16 位”,驗證會由 JavaScript 來完成,通常為了安全性和準確性,服務端會再次做一遍驗證。

1. 驗證目標

表單用于收集信息,從 HTML 上講,表單內容使用 form 標簽進行包裹。

<form action="/login">
  <label>
    用戶名:<input type="text">
  </label>

  <label>
    密碼:<input type="text">
  </label>

  <div>
    <button type="submit">登入</button>
  </div>
</form>

這就是一個相對簡單的表單,其中包含文本框(input標簽)與按鈕(button標簽),并使用 form 標簽進行包裹。

利用 form 標簽,再觸發其 submit 事件時,會將表單內容收集后提交個體 action 屬性配置的路徑。

單其實把 form 標簽去掉,在頁面上展示的效果幾乎是一樣的。

<label>
  用戶名:<input type="text">
</label>

<label>
  密碼:<input type="text">
</label>

<div>
  <button type="submit">登入</button>
</div>·

所以自出現 AJAX 技術后,很多開發者都不再書寫 form 標簽,直接使用其他元素對表單內容進行包裹,因為業務上可能不需要使用 form 標簽的特性來提交表單。

其實不論是使用表單,還是不使用表單,表單的驗證都是針對所有表單項的,即輸入框、單選項、多選項等。

在表單提交之前,需要對寫著表單項的內容做校驗,然后攔截提交操作。

2. 獲取表單內容

獲取表單內容,實際上就是取到表單項對應的 DOM 節點的值。

獲取 DOM 節點的方式非常多,前面的章節也有介紹。

<style>
  h3 {margin-top: 0;color: #4caf50;}
  .login {width: 300px;padding: 32px;box-shadow: 2px 2px 10px rgba(0, 0, 0, .1);position: fixed;top: 40%;left: 50%;transform: translate(-50%, -50%);}
  .form-item {display: flex;margin-bottom: 16px;border-bottom: 1px solid #ccc;}
  .form-item .title {width: 70px;color: #666;font-size: 14px;}
  .form-item .content {flex: 1;}
  .form-item .content input {width: 100%;border: 0 none;padding: 2px 8px;outline: none;font-size: 16px;}
  .login-btn {width: 100%;border: 0 none;background-color: #4caf50;color: white;margin-top: 16px;outline: none;height: 32px;}
  .login-btn:active {background-color: #2da050;}
</style>

<form name="login-form" class="login">
  <h3>登入</h3>
  <label class="form-item">
    <div class="title">用戶名</div>
    <div class="content">
      <input id="account" class="account" name="account" type="text">
    </div>
  </label>

  <label class="form-item">
    <div class="title">密碼</div>
    <div class="content">
      <input name="pwd" type="password">
    </div>
  </label>

  <div>
    <button class="login-btn" type="submit">登入</button>
  </div>
</form>

<script>
  var account1 = document.getElementById('account');
  var account2 = document.getElementsByName('account');
  var account3 = document.getElementsByClassName('account');

  alert(account1 === account2[0]);
  alert(account1 === account3[0]);

  var account4 = document.forms['login-form']['account'];

  alert(account1 === account4);

  console.log(document.forms['login-form'].elements);
</script>

前三種獲取節點的方式讀者都已經熟悉了。

account4 的獲取方式稍微有點不一樣,document.forms 是文檔內的表單集合,其可以通過表單的 id 和 form 的屬性,取到具體的某個表單。

取到表單后,還可以直接使用表單項的 name 屬性取到對應的表單項,使用 elements 可以取到這個表單下的所有表單項。

3. 校驗表單項

獲取到表單項后,就可以對表單項的值做判斷了,如密碼必須是 6-16 位:

<style>
  h3 {margin-top: 0;color: #4caf50;}
  .login {width: 300px;padding: 32px;box-shadow: 2px 2px 10px rgba(0, 0, 0, .1);position: fixed;top: 40%;left: 50%;transform: translate(-50%, -50%);}
  .form-item {display: flex;margin-bottom: 16px;border-bottom: 1px solid #ccc;}
  .form-item .title {width: 70px;color: #666;font-size: 14px;}
  .form-item .content {flex: 1;}
  .form-item .content input {width: 100%;border: 0 none;padding: 2px 8px;outline: none;font-size: 16px;}
  .login-btn {width: 100%;border: 0 none;background-color: #4caf50;color: white;margin-top: 16px;outline: none;height: 32px;}
  .login-btn:active {background-color: #2da050;}
</style>

<form name="login-form" class="login" action="https://imooc.com">
  <h3>登入</h3>
  <label class="form-item">
    <div class="title">用戶名</div>
    <div class="content">
      <input autocomplete="off" id="account" class="account" name="account" type="text">
    </div>
  </label>

  <label class="form-item">
    <div class="title">密碼</div>
    <div class="content">
      <input autocomplete="off" name="pwd" type="password">
    </div>
  </label>

  <div>
    <button class="login-btn" type="submit">登入</button>
  </div>
</form>

<script>
  var loginForm = document.forms['login-form'];
  var pwdEle = loginForm.pwd;

  loginForm.onsubmit = function(e) {
    var pwd = pwdEle.value;

    if (pwd.length < 6 || pwd.length > 16) {
      alert('密碼長度 6-16');
      return false; // 可以使用 return e.preventDefault() 代替
    }

    setTimeout(function() {
      alert('登入成功,馬上跳轉!');
    }, 1000);
  };
</script>

這里獲取到了表單元素,同時給表單的事件處理器屬性 onsubmit 賦值,表示在表單被提交的時候做的事情。

在事件處理器中,通過輸入框的 value 屬性獲取到了輸入的值,對值進行了長度判斷,如果長度不正確則返回 false,表單則會終止提交。
如果正確,則會根據 form 標簽的 target 屬性進行提交。

需要注意的是,這里如果使用 addEventListener 來監聽 submit 事件,必須使用 preventDefault 來阻止默認事件,即阻止表單提交,不能使用 return false;。

var loginForm = document.forms['login-form'];
var pwdEle = loginForm.pwd;

loginForm.addEventListener('submit', function(e) {
  var pwd = pwdEle.value;

  if (pwd.length < 6 || pwd.length > 16) {
    alert('密碼長度 6-16');
    e.preventDefault(); // 代替return false
    return;
  }

  setTimeout(function() {
    alert('登入成功,馬上跳轉!');
  }, 1000);
});

4. 不使用 form 提交表單

不使用 form 標簽來提交表單,通常都是使用 AJAX 進行數據交互的情況。

這個時候就不需要攔截 form 的提交行為了。

<style>
  h3 {margin-top: 0;color: #4caf50;}
  .login {width: 300px;padding: 32px;box-shadow: 2px 2px 10px rgba(0, 0, 0, .1);position: fixed;top: 40%;left: 50%;transform: translate(-50%, -50%);}
  .form-item {display: flex;margin-bottom: 16px;border-bottom: 1px solid #ccc;}
  .form-item .title {width: 70px;color: #666;font-size: 14px;}
  .form-item .content {flex: 1;}
  .form-item .content input {width: 100%;border: 0 none;padding: 2px 8px;outline: none;font-size: 16px;}
  .login-btn {width: 100%;border: 0 none;background-color: #4caf50;color: white;margin-top: 16px;outline: none;height: 32px;}
  .login-btn:active {background-color: #2da050;}
</style>

<div class="login">
  <h3>登入</h3>
  <label class="form-item">
    <div class="title">用戶名</div>
    <div class="content">
      <input autocomplete="off" id="account" class="account" name="account" type="text">
    </div>
  </label>

  <label class="form-item">
    <div class="title">密碼</div>
    <div class="content">
      <input autocomplete="off" name="pwd" type="password">
    </div>
  </label>

  <div>
    <button class="login-btn" type="button">登入</button>
  </div>
</div>

<script>
var loginBtn = document.querySelector('.login-btn');
var pwdEle = document.querySelector('[name="pwd"]');

function login(cb) {
  // 假裝登入花了 1 秒
  setTimeout(function() {
    alert('登入成功');
    cb && cb();
  }, 1000);
}

loginBtn.addEventListener('click', function() {
  var pwd = pwdEle.value;

  if (pwd.length < 6 || pwd.length > 16) {
    alert('密碼長度 6-16');
    return;
  }

  login(function() {
    window.location.href = 'https://imooc.com';
  });
});
</script>

使用這種方式,就可以自主控制流程,不需要再考慮 form 標簽的行為。

5. 小結

校驗表單非常常見,校驗表單的場景很多時候遠沒有本篇介紹的這么簡單,有時候數據校驗的格式非常復雜,需要結合正則、校驗算法等方式來解決,如嚴格的身份證驗證就需要結合身份證算法。

但表單的校驗總的來說都遵循獲取表單元素、獲取表單元素的值、對值進行判斷、根據判斷結果做下一步動作。