Откройте для себя путь исправления 10-летней ошибки в встроенной проверке ввода Firefox и реализации пользовательских элементов управления для улучшения разработки внешнего интерфейса.

(17 апреля 2021 г. — оригинальная статья с сайта https://lukasz.moskwa.dev/posts/a-bug-meant-to-stay)

Несколько лет назад я работал веб-разработчиком в ИТ-компании, и моя работа заключалась в том, чтобы переделывать их веб-сайт в соответствии с указаниями отдела дизайна. Это была в основном механическая работа, так как спецификации, которые мне дали, были точными и точными. Старая страница была обработана на стороне сервера через ASP.NET Core без использования каких-либо фреймворков, а поскольку новая страница должна была быть построена с помощью Angular 5, материала для заимствования было немного.

Тем временем многие функции также изменились по сравнению со старым сайтом: например, появились новые записи и новые элементы управления как среди параметров регистрации, так и параметров поиска. Это было справедливо и для всех форм.

Как мы знаем, проверка формы является фундаментальной частью разработки интерфейса. По сути, это позволяет стандартизировать данные, которые отправляются на сервер, максимально предотвращая отправку информации в неправильном формате. Более того, если все сделано правильно, это улучшает опыт пользователя, использующего портал, уведомляя его о любых ошибках в компиляции и способах их исправления.

Код

При создании регистрационной формы я помню, что следовал всем рекомендациям по дизайну, чтобы соответствовать макету и готовил функцию отправки. Поскольку не было спецификаций дизайна для неправильных входных данных и поскольку элементы управления, которые нужно было сделать, были довольно простыми, я наивно подумал об использовании собственных элементов управления HTML5. Да, эти.

<!DOCTYPE html>
<html>
  <body>
    <h1>The input required attribute</h1>
    <form action="/action_page.php">
      <label for="username">Username:</label>
      <input type="text" id="username" name="username" required>
      <label for="password">Password:</label>
      <input type="password" id="password" name="password" required>
      <input type="submit">
    </form>
  </body>
</html>

Я не думал, что что-то не так, и, убедившись в браузере, что поведение соответствует моим ожиданиям, я продолжил разработку.

Через несколько дней я получил электронное письмо от тестировщика с сообщением об ошибке в этой самой форме. Судя по описанию ошибки, его браузер дал сбой, когда он ввел неверные данные в один из входов. Ошибка была очень специфичной: «пузырь», сообщающий о недопустимом поле, не указывал на то же поле, на которое прокручивалась страница. Как ни банально это может показаться, это все же неточность и, следовательно, ее необходимо исправить.

Изначально я не понимал, как это возможно, что это не работает: я предполагал, что CSS страницы как-то борется (и проигрывает) нативным компонентам браузера. На самом деле это происходило только в Firefox. Я мог бы понять подобное поведение в Safari, но, увидев его в своем любимом браузере, некоторые сомнения пошатнулись.

Как только я пришел к выводу, что это не может быть связано с CSS (ни одно из моих изменений не повлияло на окончательный результат в прокрутке), я начал искать в Интернете, чтобы узнать, не сталкивался ли кто-нибудь с такой же проблемой. Возможно, это была версия Firefox. Возможно, еще один фактор, который я не учел.

Охота

Несмотря на несколько неточный поисковый запрос (я не знал, как точно описать проблему), мне стали попадаться первые вопросы на StackOverflow, посвященные этой проблеме:





Скорее всего, это была ошибка. Август 2015 г. 4 года назад и с тех пор никаких обновлений по заявке. Пришло время еще глубже залезть в кроличью нору, потому что я не хотел верить, что мне пришлось менять реализацию из-за неисправленной ошибки в одном из браузеров.



С этим GIF, который идеально воспроизвел проблему

Но больше всего меня потрясла вторая ссылка.



10 лет? Хорошо, они определенно забыли об этом здесь. Хотя я не был в восторге от этой идеи, пришло время найти обходной путь, пусть даже только для браузера.

Исправление

Чтобы пользователь не ввел неправильные данные или забыл ввести данные, необходимо реализовать элементы управления другим способом. Для этого достаточно использовать комбинацию JavaScript и CSS:

<!DOCTYPE html>
<html>
  <style src="./style.css"></style>
  <body>
    <h1>The input required attribute</h1>
    <form name="loginForm" action="/action_page.php" onsubmit="return validateForm()">
      <label for="username">Username:</label>
      <input type="text" id="username" name="username">
      <label for="password">Password:</label>
      <input type="password" id="password" name="password">
      <input type="submit">
    </form>
  </body>

  <script src="./validate.js"></script>
</html>

CSS:

.error {
  border: 1px solid red;
  color: red;
}

и код JavaScript.

function validateForm(){
    const formFields = document.forms["loginForm"]
    for(const field in formFields){
      if(formFields[field].value === ""){
        formFields[field].classList.add("error")
      } else {
        formFields[field].classList.remove("error")
      }
    }
  }