- 做者:陳大魚頭
- github: KRISACHAN
魚頭曾在 『極限版』不摻水,用純 CSS 來實現超颯的表單驗證功能 一文中分享過一個花裏胡哨的 純 CSS 的表單驗證功能 。雖然僅僅依賴 CSS 是沒法知足咱們的平常開發需求的,可是配合着各類原生的 form 驗證 API ,狀況又不同了。html
下面就讓咱們來了解一下 。git
每個原生的表單組件都會有一個用於描述元素的驗證狀態的對象 —— ValidityState 。github
代碼以下:api
帳號:<input data-title="帳號" placeholder="請輸入正確的帳號" pattern="\w{6,10}" name="account" type="text" required id="input-text" /> <script> 'use strict'; const inputText = document.querySelector('#input-text'); inputText.addEventListener('input', event => { console.table(inputText.validity); }); </script>
輸出以下:瀏覽器
具體屬性以下:ui
屬性 | 可選值 | 說明 |
---|---|---|
valueMissing(只讀) | true / false |
當表單元素設置了 required 屬性,且 value 爲空時則爲 true ,不然爲 false 。此屬性關聯僞類 :valid / :invalid 。 |
typeMismatch(只讀) | true / false |
當表單元素輸入的值與類型不匹配時爲 true ,不然爲 false 。此屬性關聯僞類 :valid / :invalid 。 |
patternMismatch(只讀) | true / false |
當表單元素輸入的值與 pattern 屬性的規則不匹配時爲 true ,不然爲 false 。此屬性關聯僞類 :valid / :invalid 。 |
tooLong(只讀) | true / false |
當表單元素輸入的值長度超過 maxlength 屬性時 爲 true ,不然爲 false 。此屬性關聯僞類 :valid / :invalid 。 |
tooShort(只讀) | true / false |
當表單元素輸入的值長度少於 minlength 屬性時 爲 true ,不然爲 false 。此屬性關聯僞類 :valid / :invalid 以及 :in-range / :out-of-range 。 |
rangeUnderflow(只讀) | true / false |
當表單元素輸入的值少於 min 屬性時 爲 true ,不然爲 false 。此屬性關聯僞類 :valid / :invalid 以及 :in-range / :out-of-range 。 |
rangeOverflow(只讀) | true / false |
當表單元素輸入的值大於 max 屬性時 爲 true ,不然爲 false 。此屬性關聯僞類 :valid / :invalid 以及 :in-range / :out-of-range 。 |
stepMismatch(只讀) | true / false |
當表單元素輸入的值與 step 的值不匹配 時爲 true ,不然爲 false 。此屬性關聯僞類 :valid / :invalid 以及 :in-range / :out-of-range 。 |
badInput(只讀) | true / false |
當表單元素輸入的值不完整且 UA 認爲當前狀態的表單不該該被提交時爲 true ,不然爲 false 。 |
customError(只讀) | true / false |
當表單元素的錯誤信息是由 setCustomValidity() 方法調用展現時爲 true ,不然爲 false 。 |
valid(只讀) | true / false |
當表單元素驗證經過時爲 true ,不然爲 false 。此屬性關聯僞類 :valid / :invalid 。 |
當表單元素驗證正確時則返回 ''
,不然則返回默認或者經由setCustomValidity()
方法設置的錯誤信息。spa
效果以下:code
代碼以下:orm
帳號:<input data-title="帳號" placeholder="請輸入正確的帳號" pattern="\w{6,10}" name="account" type="text" required id="input-text" /> <script> 'use strict'; const inputText = document.querySelector('#input-text'); inputText.addEventListener('input', event => { console.table(inputText.validationMessage); // 驗證錯誤時則返回 「請與所請求的格式保持一致。」 }); </script>
一個只讀屬性,當表單元素須要驗證時返回 true
,不然則爲 false
。htm
效果以下:
代碼以下:
帳號:<input data-title="帳號" placeholder="請輸入正確的帳號" pattern="\w{6,10}" name="account" type="text" required id="input-text" /> <script> 'use strict'; const inputText = document.querySelector('#input-text'); inputText.addEventListener('input', event => { console.table(inputText.willValidate); // true }); </script>
setCustomValidity()
用於設置表單元素 validationMessage
的值。當設置 setCustomValidity()
以後,validity.customError
就會變成 true
。若是須要重置,則輸入空字符串便可。
咱們看看效果圖:
代碼以下:
<form class="form" id="form" method="get" action="/api/form"> 帳號: <input id="account" data-title="帳號" placeholder="請輸入正確的帳號" pattern="\w{6,10}" name="account" type="text" required /> <input id="submit" name="button" type="submit" value="提交" /> </form> <script> 'use strict'; account.setCustomValidity('自定義錯誤!'); form.addEventListener('submit', event => { event.preventDefault(); }); </script>
checkValidity()
用於檢查當前表單元素或整個表單的值是否經過驗證,若是是則爲 true
,不然則爲 false
。
效果以下:
代碼以下:
帳號:<input data-title="帳號" placeholder="請輸入正確的帳號" pattern="\w{6,10}" name="account" type="text" required id="input-text" /> <script> 'use strict'; const inputText = document.querySelector('#input-text'); inputText.addEventListener('input', event => { console.table(inputText.checkValidity()); }); </script>
reportValidity()
用於觸發以及檢查表單元素的值是否經過驗證,若是是則爲 true
,不然則爲 false
。
效果以下:
代碼以下:
帳號:<input data-title="帳號" placeholder="請輸入正確的帳號" pattern="\w{6,10}" name="account" type="text" required id="input-text" /> <script> 'use strict'; const inputText = document.querySelector('#input-text'); console.log(inputText.reportValidity()); </script>
以上 API 兼容性以下:
圖片來自:https://caniuse.com/constraint-validation
咱們看效果:
代碼以下:
<style> .form > input { margin-bottom: 10px; } </style> <form class="form" id="form" method="get" action="/api/form"> 帳號: <input id="account" data-message="請輸入正確的帳號" data-title="帳號" placeholder="請輸入正確的帳號" pattern="\w{6,10}" name="account" type="text" required /> <br /> 密碼: <input id="password" data-message="請輸入正確的密碼" data-title="密碼" placeholder="請輸入正確的密碼" pattern="\w{6,10}" name="password" type="password" required /> <br /> <input id="submit" name="button" type="submit" value="提交" /> </form> <script> 'use strict'; const inputs = [account, password]; inputs.forEach(input => { input.addEventListener('input', () => { input.setCustomValidity(''); input.checkValidity(); }); input.addEventListener('invalid', event => { const { message } = event.target.dataset; const { validity: { valid } } = input; input.setCustomValidity(''); if (!valid) { input.setCustomValidity(message); }; }); }); </script>
以上例子能夠在魚頭的 Codepen :https://codepen.io/krischan77/pen/RwGLaxa 上查看。
魚頭注:Mmmmm,功能卻是挺好的,若是不是原生的組件樣式太醜,不一樣瀏覽器的表現不一致,並且樣式還不能修改,我想用原生 API 開發的人應該會不少。。。搞不懂爲啥 W3C 不暴露出樣式修改的屬性。。。