使用JavaScript即時表單驗證
實時表單驗證:提升用戶體驗的微妙改進
核心要點:
- JavaScript 可用於實現實時表單驗證,此功能可為用戶提供輸入有效性的即時反饋,從而提升用戶體驗並維護數據完整性,確保僅提交有效數據。
- HTML5 屬性
pattern
和required
可用於定義表單元素的有效輸入範圍。如果瀏覽器不支持這些屬性,則其值可用作 JavaScript 兼容性填充程序的基礎。 -
aria-invalid
屬性可用於指示字段是否無效。此屬性提供輔助功能信息,並可用作 CSS 鉤子以直觀地指示無效字段。 - JavaScript 函數
instantValidation()
測試字段並執行實際驗證,控制aria-invalid
屬性以指示字段的狀態。此函數可以綁定到onchange
事件以提供實時表單驗證。
HTML5 引入了幾個用於實現基於瀏覽器的表單驗證的新屬性。 pattern
屬性是一個正則表達式,用於定義文本區域元素和大多數輸入類型的有效輸入範圍。 required
屬性指定字段是否必填。對於不支持這些屬性的舊版瀏覽器,我們可以使用它們的值作為兼容性填充程序的基礎。我們還可以使用它們來提供更有趣的增強功能——實時表單驗證。
需要注意的是,不要過度使用驗證,以免破壞正常的瀏覽行為並妨礙用戶操作。例如,我見過一些表單,無法使用 Tab 鍵離開無效字段——JavaScript 被用來(更確切地說,是被濫用)強制焦點停留在字段內,直到其有效為止。這非常不利於用戶體驗,並且直接違反了輔助功能指南。
本文將介紹一種侵入性較小的實現方法。它甚至不是完整的客戶端驗證——它只是一種細微的用戶體驗增強,以可訪問的方式實現,在我測試腳本時發現它幾乎與 Firefox 當前原生實現的功能相同!
基本概念
在最新版本的 Firefox 中,如果必填字段為空或其值與模式不匹配,則該字段將顯示紅色邊框,如下圖所示:
當然,這不會立即發生。如果發生這種情況,則每個必填字段默認都會顯示該邊框。相反,只有在您與字段交互後才會顯示這些邊框,這基本上(雖然不完全)類似於 onchange
事件。
因此,我們將使用 onchange
作為觸發事件。或者,我們可以使用 oninput
事件,該事件只要在字段中鍵入或粘貼任何值就會觸發。但這真的太“即時”了,因為它很容易在快速連續鍵入時反复觸發,從而產生閃爍效果,這會讓一些用戶感到厭煩或分心。而且,無論如何,oninput
不會從編程輸入中觸發,而 onchange
會觸發,我們可能需要它來處理來自第三方插件的自動完成等操作。
定義HTML和CSS
讓我們看一下我們的實現,從它所基於的 HTML 開始:
<form action="#" method="post"> <fieldset> <legend><strong>Add your comment</strong></legend> <p> <label for="author">Name <abbr title="Required">*</abbr></label> <input aria-required="true" id="author" name="author" pattern="^([- \w\d\u00c0-\u024f]+)$" required="required" size="20" spellcheck="false" title="Your name (no special characters, diacritics are okay)" type="text" value="" > </p> <p> <label for="email">Email <abbr title="Required">*</abbr></label> <input aria-required="true" id="email" name="email" pattern="^(([-\w\d]+)(\.[-\w\d]+)*@([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2})$" required="required" size="30" spellcheck="false" title="Your email address" type="email" value="" > </p> <p> <label for="website">Website</label> <input id="website" name="website" pattern="^(http[s]?:\/\/)?([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2}(\/([-~%\.\(\)\w\d]*\/*)*(#[-\w\d]+)?)?$" size="30" spellcheck="false" title="Your website address" type="url" value="" > </p> <p> <label for="text">Comment <abbr title="Required">*</abbr></label> <textarea aria-required="true" cols="40" id="text" name="text" required="required" rows="10" spellcheck="true" title="Your comment" ></textarea> </p> </fieldset> <fieldset> <input name="preview" type="submit" value="Preview"> <input name="save" type="submit" value="Submit Comment"> </fieldset> </form>
此示例是一個簡單的評論表單,其中一些字段是必填的,一些字段經過驗證,一些字段同時滿足這兩個條件。具有 required
屬性的字段也具有 aria-required
屬性,以便為不支持新輸入類型的輔助技術提供後備語義。
ARIA 規範還定義了 aria-invalid
屬性,我們將使用它來指示字段是否無效(HTML5 中沒有等效屬性)。 aria-invalid
屬性顯然提供了輔助功能信息,但它也可以用作 CSS 鉤子來應用紅色邊框:
input[aria-invalid="true"], textarea[aria-invalid="true"] { border: 1px solid #f00; box-shadow: 0 0 4px 0 #f00; }
我們可以只使用 box-shadow
而不用管邊框,坦白說這樣看起來會更好,但這樣一來,在不支持 box-shadow
的瀏覽器(例如 IE8)中就沒有指示了。
添加JavaScript
現在我們有了靜態代碼,我們可以添加腳本了。首先,我們需要一個基本的 addEvent()
函數:
function addEvent(node, type, callback) { if (node.addEventListener) { node.addEventListener(type, function(e) { callback(e, e.target); }, false); } else if (node.attachEvent) { node.attachEvent('on' + type, function(e) { callback(e, e.srcElement); }); } }
接下來,我們需要一個函數來確定是否應該驗證給定字段,該函數只需測試它既未禁用也未只讀,並且它具有 pattern
或 required
屬性:
function shouldBeValidated(field) { return ( !(field.getAttribute("readonly") || field.readonly) && !(field.getAttribute("disabled") || field.disabled) && (field.getAttribute("pattern") || field.getAttribute("required")) ); }
前兩個條件可能看起來很冗長,但它們是必要的,因為元素的 disabled
和 readonly
屬性不一定反映其屬性狀態。例如,在 Opera 中,具有硬編碼屬性 readonly="readonly"
的字段仍然會為其 readonly
屬性返回 undefined
(點屬性只匹配通過腳本設置的狀態)。
一旦我們獲得了這些實用程序,我們就可以定義主驗證函數,該函數測試字段,然後根據需要執行實際驗證:
function instantValidation(field) { if (shouldBeValidated(field)) { var invalid = (field.getAttribute("required") && !field.value) || (field.getAttribute("pattern") && field.value && !new RegExp(field.getAttribute("pattern")).test(field.value)); if (!invalid && field.getAttribute("aria-invalid")) { field.removeAttribute("aria-invalid"); } else if (invalid && !field.getAttribute("aria-invalid")) { field.setAttribute("aria-invalid", "true"); } } }
因此,如果字段是必填的但沒有值,或者它具有模式和值,但值與模式不匹配,則該字段無效。
由於模式已經定義了正則表達式的字符串形式,所以我們只需要將該字符串傳遞給 RegExp
構造函數,它就會創建一個我們可以針對該值進行測試的正則表達式對象。但是,我們必須預先測試該值以確保它不為空,這樣正則表達式本身就不必考慮空字符串。
一旦我們確定了字段是否無效,我們就可以控制它的aria-invalid
屬性來指示該狀態——將其添加到尚未具有該屬性的無效字段中,或將其從具有該屬性的有效字段中刪除。很簡單!最後,為了使這一切都能運行,我們需要將驗證函數綁定到 onchange
事件。它應該像這樣簡單:
<form action="#" method="post"> <fieldset> <legend><strong>Add your comment</strong></legend> <p> <label for="author">Name <abbr title="Required">*</abbr></label> <input aria-required="true" id="author" name="author" pattern="^([- \w\d\u00c0-\u024f]+)$" required="required" size="20" spellcheck="false" title="Your name (no special characters, diacritics are okay)" type="text" value="" > </p> <p> <label for="email">Email <abbr title="Required">*</abbr></label> <input aria-required="true" id="email" name="email" pattern="^(([-\w\d]+)(\.[-\w\d]+)*@([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2})$" required="required" size="30" spellcheck="false" title="Your email address" type="email" value="" > </p> <p> <label for="website">Website</label> <input id="website" name="website" pattern="^(http[s]?:\/\/)?([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2}(\/([-~%\.\(\)\w\d]*\/*)*(#[-\w\d]+)?)?$" size="30" spellcheck="false" title="Your website address" type="url" value="" > </p> <p> <label for="text">Comment <abbr title="Required">*</abbr></label> <textarea aria-required="true" cols="40" id="text" name="text" required="required" rows="10" spellcheck="true" title="Your comment" ></textarea> </p> </fieldset> <fieldset> <input name="preview" type="submit" value="Preview"> <input name="save" type="submit" value="Submit Comment"> </fieldset> </form>
但是,為了使這能夠工作,onchange
事件必須冒泡(使用通常稱為事件委託的技術),但在Internet Explorer 8 及更早版本中,onchange
事件不會冒泡。我們可以選擇忽略這些瀏覽器,但我認為這將是一種遺憾,尤其是在問題如此容易解決的情況下。它只是意味著代碼更複雜一些——我們必須獲取輸入和文本區域元素的集合,遍歷它們並將 onchange
事件分別綁定到每個字段:
input[aria-invalid="true"], textarea[aria-invalid="true"] { border: 1px solid #f00; box-shadow: 0 0 4px 0 #f00; }
結論和展望
就是這樣——一個簡單且非侵入性的實時表單驗證增強功能,提供可訪問和直觀的提示,以幫助用戶完成表單。
這個腳本實現後,我們實際上只需要幾步就能完成一個完整的兼容性填充程序。這樣的腳本超出了本文的範圍,但是如果您想進一步開發它,所有基本模塊都在這裡——測試是否應該驗證字段,根據模式和/或 required
驗證字段,以及綁定觸發事件。
我必須承認,我不確定它是否真的值得!如果您已經有了此增強功能(在IE7 及所有現代瀏覽器中都能工作),並且考慮到您別無選擇,也必須實現服務器端驗證,並且考慮到支持pattern
和required
的瀏覽器已經使用它們進行預提交驗證——考慮到所有這些,真的還有必要添加另一個兼容性填充程序嗎?
(此處可以添加關於實時驗證的常見問題解答部分,內容與原文檔中的FAQs部分相同)
以上是使用JavaScript即時表單驗證的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。
