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

2023-Feb-03

При вводе пароля легко ошибиться поскольку символы, которые вводит пользователь - скрыты. В этом уроке добавим кнопку показать пароль для форм ввода данных на сайтах, добавим анимацию оставшегося до скрытия пароля времени. Технологии, которые будем применять - 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.

Загрузить файл с кодом: Download

Статьи

Подсвечиваем НЕ ЛАТИНСКИЕ СИМВОЛы в коде и тексте
Тотальное руководство по элементу Select в JavaScript
Задача собеседования: получаем email из строки