Перевірка валідності форми на JavaScript і HTML5 - це легко

  1. Визначення HTML і CSS
  2. Додавання JavaScript
  3. Дивимося що вийшло

HTML5 представляє кілька нових атрибутів для реалізації перевірки на основі браузера. pattern Атрибут є регулярним виразом, яке визначає діапазон допустимих входів для textarea елементів і більшість типів input. required Атрибут визначає, потрібно чи поле. Для застарілих браузерів, які не реалізують ці атрибути, ми можемо використовувати їх значення в якості основи для поліфілла. Ми також можемо використовувати їх для забезпечення більш цікавого удосконалення - миттєвої перевірки форми.

Ми повинні бути дуже обережні, щоб не захопитися, створюючи надмірно агресивну перевірку, яка порушує природну поведінку браузера і потрапляє на людей. Наприклад, я бачив форми, в яких неможливо натиснути Tab, тобто виключити перейти на інший input. дуже зловживати javascript, щоб змусити фокус залишатися всередині поля, поки він не буде дійсним. Це дуже погане використання і прямо суперечить рекомендаціям по доступності .

Те, що ми збираємося зробити в цій статті, набагато менш нав'язливо. Це навіть не повна перевірка на стороні клієнта - це просто тонке вдосконалення юзабіліті, реалізоване доступним способом, яке (як я виявив при тестуванні скрипта) майже ідентично тому, що тепер робить 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> <button name =" preview "type =" submit "> Preview </ button> <button name =" save "type =" submit "> Submit Comment </ button> </ fieldset> </ form>

Цей приклад є простою форму коментарів, в якій потрібні деякі поля, деякі перевіряються. Області, які required також мають, щоб забезпечити запасну семантику для допоміжних технологій, які не розуміють нових aria-required input типи.

Специфікація ARIA також визначає атрибут, і це те, що ми збираємося використовувати, щоб вказати, коли поле є неприпустимим (для якого немає еквівалентного атрибута в HTML5). Атрибут, очевидно, забезпечує доступну інформацію, але він може бути також використаний як CSS гака, щоб застосувати червоний контур: aria-invalid

input [aria-invalid = "true"], textarea [aria-invalid = "true"] {border: 1px solid # f00; box-shadow: 0 0 4px 0 # f00; }

Ми могли б просто використовувати і не турбуватися про це, і, відверто кажучи, це виглядало б краще, але тоді у нас не було б ніяких ознак в браузерах, які не підтримують тіней коробок, таких як IE8.box-shadow border

Додавання 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);}); }}

Потім нам знадобиться функція для визначення того, чи повинна ця поле бути перевірено, що просто перевіряє, що він не відключений і не читається, і що він має або атрибут, patter nлібо required атрибут:

function shouldBeValidated (field) {return (! (field.getAttribute ( "readonly") || field.readonly) &&! (field.getAttribute ( "disabled") || field.disabled) && (field.getAttribute ( "pattern" ) || field.getAttribute ( "required"))); }

Перші дві умови можуть здатися багатослівними, але вони необхідні, тому що елементи disabled і readonly властивості не обов'язково будуть відображати стану атрибутів. В Opera, наприклад, поле з жорстко закодованим атрибутом, як і раніше буде повертатися для свого властивості (властивість dot тільки відповідає станам, які задаються через скрипти) .readonly = "readonly" undefinedreadonly

Як тільки ми отримаємо ці утиліти, ми можемо визначити основну функцію перевірки, яка перевіряє поле і потім виконує фактичну перевірку, якщо це може бути застосовано:

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"); }}}

Таким чином поле недійсне якщо воно потрібне, але не має значення, чи воно має шаблон і значення, але значення не відповідає шаблоном.

Оскільки patternу же заданий строковим регулярним виразом, то нам потрібно передати цей рядок RegExp конструктору і створити об'єкт регулярного виразу, який ми можемо перевірити за значенням. Але нам потрібно попередньо перевірити значення, щоб переконатися, що воно не порожнє, так що самому регулярному виразу не потрібно враховувати порожні рядки.

Як тільки ми встановили, чи є поле неприпустимим, ми можемо управляти його атрибутом, вказуючи, що це додавання в неприпустиме поле, яке його ще не має значення, щоб все це входило в дію, нам потрібно прив'язати функцію перевірки до події. Це повинно бути так просто: aria-invalidonchange

addEvent (document, "change", function (e, target) {instantValidation (target);});

Однак для того, щоб працювати, onchange події повинні пузиритися (використовуючи техніку, яка зазвичай відома як делегування подій), але в Internet Explorer 8 і раніше onchange події не пузиряться. Ми могли б просто ігнорувати ці браузери, але я думаю, що це був би ганьба, особливо коли проблема настільки проста в обході. Це просто означає трохи більш складний код - нам потрібно отримати колекції input і textarea елементи, перебрати їх і зв'язати onchange подія з кожним полем окремо:

var fields = [document.getElementsByTagName ( "input"), document.getElementsByTagName ( "textarea")]; for (var a = fields.length, i = 0; i <a; i ++) {for (var b = fields [i] .length, j = 0; j <b; j ++) {addEvent (fields [i] [ j], "change", function (e, target) {instantValidation (target);}); }}

Дивимося що вийшло

Таким чином, ми маємо просту і неінтрузівного удосконалення для миттєвої перевірки форми, надаючи доступні і візуальні підказки, щоб допомогти користувачам заповнити форми.

Ви можете подивитися демо нижче:

Після того, як цей скриптинг буде реалізований, насправді у нас всього лише пара пропусків і вилучень від повного полігону. Такий сценарій виходить за рамки цієї статті, але якщо ви хочете його розвивати далі, всі базові блоки є - перевірка того, чи потрібно перевіряти поле, перевіряти поле проти шаблону і / або вимагати, а також зв'язати тригер Заходи.

Я повинен зізнатися, я не впевнений, що це дійсно того варте! Якщо у вас вже є це удосконалення (яке працює у всіх сучасних браузерах назад в IE7), і з огляду на, що у вас немає іншого вибору, окрім як виконати перевірку на стороні сервера, а також з урахуванням того, що браузери, які підтримують pattern і required вже використовують їх для перевірки перед відправкою - З огляду на все це, чи дійсно є якась точка, що додає ще один поліполк?

W \ d] +) (\. [- \ w \ d] +) * (\. ([a-zA-Z] {2, 5} | [\ d] {1,3})) {1,2} (\ / ([- ~% \. \ (\) \ w \ d] * \ / *) * (# [- \ w \ d] +)?