Кнопка "Показать пароль" на JavaScript + анимация

При вводе пароля легко ошибиться поскольку символы, которые вводит пользователь - скрыты. В этом уроке добавим кнопку показать пароль для форм ввода данных на сайтах, добавим анимацию оставшегося до скрытия пароля времени. Технологии, которые будем применять - JavaScript, для оформления - Boostrap. Так будет выглядеть результат:
Список тем, которые будут затронуты:
- работа с DOM
- работа с атрибутами
- работа с интервалами - таймерами
- разбор багов при работе с интервалами
Для начала создадим стандартную структуру - папку приложения, файл index.html, app.js, app.css, создадим стандартную верстку в html и подключим javascript и css файлы.
Код будем писать по шагам. Для начала выполним работу на скелете, а затем добавим оформление. Итак, создадим верстку вида:
<input type="password" id="password" value="qwerty123">
<button type="button" id="show-password-btn">Show</button>
Этого достаточно для начала работы. Чтобы каждый раз не вводить пароль - добавлено value, конечно же в реальном проекте это не нужно. Поставим задачу - при нажатии кнопки show показывать пароль на какое-то время, а затем скрывать. Логика кода - изменять атрибут type="password" на type="text" и спустя промежуток времени - возвращать атрибуты в исходное состояние.
Пишем код JavaScript
Пропишем необходимые для работы данные в виде констант:
const showPasswordButton = document.querySelector('#show-password-btn');
const passwordInput = document.querySelector('#password');
const TIME_SHOW_PASSWORD = 5000;
где TIME_SHOW_PASSWORD - время, на которое будем показывать пароль.
Теперь необходимо выполнить проверку - если константа showPasswordButton не пустая, то добавить событие - функцию показать пароль.
if (showPasswordButton && passwordInput) showPasswordButton.addEventListener('click', showPassword);
В данном случае addEventListener - правильный выбор, поскольку на кнопку могут добавляться и другие действия по клику.
Реализуем функцию showPassword.
function showPassword(){}
Что должна делать функция? Перечисляем:
- установить атрибут type для поля пароля на text
- через интервал времени TIME_SHOW_PASSWORD вернуть все обратно.
Реализуем:
function showPassword(){
passwordInput.setAttribute('type', 'text');
setInterval(function(){
passwordInput.setAttribute('type', 'password');
}, TIME_SHOW_PASSWORD);
}
Код уже работает, однако если много раз нажимать кнопку, то становится очевидно что есть проблемы и интервал не выдерживается. Давайте добавим визуальное оформление для наглядности бага и исправим его.
Пишем CSS оформление
Сделаем анимацию поля input. Самые простые решения - сделать полоску с помощью progress ниже, также было бы просто если бы тег input был парным и вставить в него элемент, который можно изменять по ширине. Однако мы не ищем легкий путей и будем анимировать тег input с помощью фона. Если вам нужно реализовать два цвета на фоне - применим градиент. Сделаем его двуцветным - цвет и прозрачность. И зададим настройки для анимации. В CSS пропишите:
.animate-password {
background-image: linear-gradient(90deg, #ededed 50%, transparent 50%);
background-size: 200%;
background-position-x: 100%;
transition: all ease 1s;
animation-name: passwordanimation;
animation-duration: 5s;
animation-iteration-count: 1;
animation-timing-function: linear;
}
важно понять первые три строки. Мы создаем градиент из двух цветов - серый и полностью прозрачный. Без плавного перехода цвета. В начальном положении нужно чтобы серый фон был за пределами input, его небыло видно, поэтому мы растягиваем градиет в два раза больше чем input - background-size: 200% и смещаем за пределы зоны видимости background-position-x: 100%. Все остальные свойства - настройки анимации. Анимировать будем смещение фона.
Добавим анимацию, она очень простая:
@keyframes passwordanimation {
0% {background-position-x: 100%;}
100% {background-position-x: 0;}
}
И внесем изменение в функцию showPassword:
function showPassword(){
passwordInput.setAttribute('type', 'text');
passwordInput.classList.add('animate-password');
setInterval(function(){
passwordInput.setAttribute('type', 'password');
passwordInput.classList.remove('animate-password');
}, TIME_SHOW_PASSWORD);
}
Теперь нажимая кнопку - получаем анимацию поля пароля - обратный отсчет до скрытия пароля. И если постоянно нажимать кнопку, то можно увидеть проблемы - через какое-то время пароль будет отображаться и скрываться с рандомными интервалами, которые явно меньше 5 секунд. В чем же проблема? Как исправить баг setInterval?
Исправлять ошибку будем двумя путями. Первый - добавим проверку, если нажата кнопка Show и поле пароля содержит класс animate-password то будем выходить из функции, это позволит не допустить выполнение анимаций и дополнительных запусков интервалов если пароль отображается сейчас. Второе правило - чистить за собой запущенные таймеры и интервалы. Реализуем:
function showPassword(){
if (passwordInput.classList.contains('animate-password')) return;
passwordInput.setAttribute('type', 'text');
passwordInput.classList.add('animate-password');
let interval = setInterval(function(){
passwordInput.setAttribute('type', 'password');
passwordInput.classList.remove('animate-password');
clearInterval(interval);
}, TIME_SHOW_PASSWORD);
}
Проверяем - все работает!
Если у вас остались вопросы - посмотрите видео. Замечания и вопросы можно задать в чат ItGid.info.