Один из моих коллег переходит во фронтенд-команду, частью которой я раньше был. Чтобы мысленно подготовить его к путешествию во фронтенд-разработку, я отправил ему информационный бюллетень, который назвал Front-End Hack of the Day. Сейчас я отправляю их на Medium, чтобы мир мог ими насладиться.

Когда браузер автоматически заполняет поле формы, он добавляет стиль, чтобы выделить поля, которые он редактировал. В Chrome, как вы можете видеть выше, он добавляет красивый желтый цвет фона.

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

input:-webkit-autofill {
    // Much nicer
    background-color: bisque;
}

Вы можете добавлять стили, используя псевдокласс с префиксом поставщика -webkit-autofill, но если вам нужно запустить какой-то Javascript, когда поле заполняется автоматически, это становится намного сложнее.

В @ klarna / ui, наборе инструментов пользовательского интерфейса с открытым исходным кодом Klarna, мы используем шаблон плавающей метки. Метка изначально отображается как заполнитель, а когда вы начинаете вводить текст, она переходит в небольшую метку в верхней части поля.

Это делается путем прослушивания события изменения и добавления класса is-fill в поле, которое затем применяет соответствующее масштабирование и позиционирование.

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

И вот здесь-то и пригодится взлом ...

Изменить событие с помощью анимации

Мы не можем знать, когда значение поля изменяется из-за автозаполнения, но это не единственное, что происходит при автозаполнении - некоторые стили также применяются!

К сожалению, мы не можем реально прослушать изменение стиля, но мы можем прослушать начало анимации, и мы можем запустить анимацию в ответ на автозаполнение, используя ранее упомянутый псевдоним -webkit-autofill -класс.

@keyframes onAutoFillStart {  from {/**/}  to {/**/}}
@keyframes onAutoFillCancel {  from {/**/}  to {/**/}}
input:-webkit-autofill {
    // Expose a hook for JavaScript when autofill is shown
    // JavaScript can capture 'animationstart' events
    animation-name: onAutoFillStart;
    
    // Make the background color become yellow really slowly
    transition: background-color 50000s ease-in-out 0s;
}
input:not(:-webkit-autofill) {
    // Expose a hook for JS onAutoFillCancel
    // JavaScript can capture 'animationstart' events
    animation-name: onAutoFillCancel;
}

Чтобы прояснить, что здесь происходит, мы запускаем анимацию onAutoFillStart, когда активен псевдо-класс -webkit-autofill, что будет, когда Chrome автоматически заполняет ввод и изменяет фоновый цвет.

Теперь мы можем прослушивать начало этой анимации из нашего Javascript.

const AUTOFILLED = 'is-autofilled'
const onAutoFillStart = (el) => el.classList.add(AUTOFILLED)
const onAutoFillCancel = (el) => el.classList.remove(AUTOFILLED)
const onAnimationStart = ({ target, animationName }) => {
    switch (animationName) {
        case 'onAutoFillStart':
            return onAutoFillStart(target)
        case 'onAutoFillCancel':
            return onAutoFillCancel(target)
    }
}
document.querySelector('input').addEventListener('animationstart', onAnimationStart, false)

Теперь всякий раз, когда начинается воспроизведение анимации onAutoFillStart или onAutoFillCancel, будут выполняться наши соответствующие функции, в которых мы будем добавлять или удалять класс is-autofilled, или делаем то, что мы хотим делать.

Надеюсь, эта хитрость будет вам полезна. Если вы хотите узнать, как это используется в @ klarna / ui, вы можете найти реализацию поля на Github.