Обнаружение автозаполнения браузера

165

Как определить, автоматически ли браузер заполнил текстовое поле? Особенно с полями имени пользователя и пароля, которые заполняются автоматически при загрузке страницы.

Мой первый вопрос: когда это происходит в последовательности загрузки страницы? Это до или после document.ready?

Во-вторых, как я могу использовать логику, чтобы выяснить, произошло ли это? Не то чтобы я хотел, чтобы это не произошло, просто подключитесь к событию. Желательно что-то вроде этого:

if (autoFilled == true) {

} else {

}

Если возможно, я бы хотел, чтобы jsfiddle показал ваш ответ.

Возможные дубликаты

DOM событие для автозаполнения пароля браузера?

Запускаемые браузером события автозаполнения и Javascript

- Оба эти вопроса на самом деле не объясняют, какие события вызваны, они просто постоянно перепроверяют текстовое поле (не хорошо для производительности!).

Неопределенный
источник
1
Проверка занимает несколько микросекунд, тогда как интервал будет запускать проверку каждые 100 миллисекунд или около того ... как это повлияет на производительность вообще? Если бы существовало событие, запущенное браузером, я уверен, что они использовали бы его.
Esailija
Я понимаю, что вы имеете в виду, но в первой части моего вопроса все зависит от того, осознает ли JavaScript, что изменение только что произошло (например, до document.ready)
определено
1
Лучшее решение для Chrome / WebKit - использовать селектор DOM: document.querySelectorAll ('input: -webkit-autofill'); после небольшой задержки setTimeout (... код здесь ... 250);
ChrisN
в основном, я хочу автоматически войти в систему пользователя, если он автозаполнен, безумно раздражает, не входить снова, когда он автоматически выходит из системы.
Мухаммед Умер
@ChrisN Ваш комментарий - вот что на самом деле дало мне (простое) решение. Но я не вижу в этом ответа! Опубликуйте это как единое целое и пингуйте меня, чтобы я мог выразить благодарность.
Итан Камински

Ответы:

123

Проблема в том, что автозаполнение по-разному обрабатывается разными браузерами. Некоторые отправляют событие изменения, некоторые нет. Таким образом, почти невозможно подключить событие, которое запускается, когда браузер автоматически заполняет поле ввода.

  • Изменить триггер события для разных браузеров:

    • Для полей имени пользователя / пароля:

      1. Firefox 4, IE 7 и IE 8 не отправляют событие изменения.
      2. Safari 5 и Chrome 9 отправляют событие изменения.
    • Для других полей формы:

      1. IE 7 и IE 8 не отправляют событие изменения.
      2. Firefox 4 отправляет событие изменения изменения, когда пользователи выбирают значение из списка предложений и вкладки вне поля.
      3. Chrome 9 не отправляет событие изменения.
      4. Safari 5 отправляет событие изменения.

Лучше всего либо отключить автозаполнение для формы, использующейся autocomplete="off"в вашей форме, либо опрашивать через регулярные промежутки времени, чтобы узнать, заполнена ли она.

На ваш вопрос о том, заполнено ли оно в документе или перед документом. Уже снова оно варьируется от браузера к браузеру и даже от версии к версии. Для полей username / password только при выборе имени пользователя поле пароля будет заполнено. Так что в целом у вас будет очень грязный код, если вы попытаетесь присоединиться к какому-либо событию.

Вы можете прочитать это ЗДЕСЬ

afrin216
источник
26
Обратите внимание, что есть разница между автозаполнением и автозаполнением. ОП конкретно относится к браузерам, заполняющим сохраненные данные для входа в систему при загрузке страницы.
Роберт
2
Обычный хак - это взломщик важной части страницы. Событие запускается, когда мышь пользователя нажимает на кнопку или что-то подобное.
Брайс
1
@ Брайс Лично я бы пошел с событием 'размытия' из-за того, что автозаполнение происходит после входа в область ввода. Очевидно, что это не идеально, но в качестве запасного варианта для браузеров, перечисленных выше, это может быть очень полезно
JakeJ
Не забывай об этом inputсобытии. Это то, что Chrome запускает при автозаполнении (и, возможно, также при автозаполнении, если у Chrome есть это; я всегда отключаю это).
TJ Crowder
Посмотрите мой однострочный ответ, если вы просто хотите узнать, было ли значение в текстовом поле заполнено автозаполнением Google Chrome.
ThdK
72

Решение для браузеров WebKit

Из документов MDN для псевдокласса: -webkit-autofill CSS:

CSS-псевдокласс: -webkit-autofill совпадает, когда значение элемента автоматически заполняется браузером

Мы можем определить правило CSS void transition для желаемого <input>элемента, как только он будет :-webkit-autofillотредактирован. JS сможет подключиться к animationstartсобытию.

Кредиты команде Klarna UI . Смотрите их хорошую реализацию здесь:

Лев Казаков
источник
1
это, безусловно, лучшее решение! Престижность Льву здесь для этого. Спасибо за то, что поделились решением Klarna UI ... у меня ничего не получалось, пока я не нашел это. Спасатель жизни!
Брэйден Роквелл Нейпир
1
Как и правила CSS, здесь необходимы ключевые кадры github.com/klarna/ui/blob/v4.10.0/Field/styles.scss#L181-L189
user1069816
Это работало безупречно для меня! Нужно немного поиграть с ним, чтобы понять точный подход. Спасибо команде Klarna
притешь
18

Это работает для меня в последних Firefox, Chrome и Edge:

$('#email').on('blur input', function() {
    ....
});
Джеймс
источник
6
'input'! Это было самое простое решение для меня, но я проверял только автозаполнение, а не автозаполнение.
GreenRaccoon23
размытие не работает для меня с некоторыми автоматическими дополнениями
pathfinder
Ввод будет срабатывать при каждом нажатии клавиши. Если вы делаете серверный вызов, он может срабатывать часто.
RiZKiT
Отличное решение! Эта комбинация событий решает проблему с заполнением пользователем и автозаполнением браузером.
Петр Хладик
17

Для автозаполнения Google Chrome это работает для меня:

if ($("#textbox").is(":-webkit-autofill")) 
{    
    // the value in the input field of the form was filled in with google chrome autocomplete
}
ThdK
источник
Это сработало и для меня. Я пробовал сотни решений, и никто не работал. Большое спасибо, спаси мой день и все время, пока я искал решение.
Perozzo
4
этот подход приводит к ошибке: «Синтаксическая ошибка, нераспознанное выражение: неподдерживаемое псевдо: -webkit-autofill» в других браузерах (я пробовал в Firefox)
anvita surapaneni
1
Не работает на chrome, как и в 2020 году, также выдает ошибку нераспознанное выражение: неподдерживаемое псевдо: -webkit-autofill
Лев
15

На случай, если кто-то ищет решение (как и я сегодня) для прослушивания изменений автозаполнения браузера, вот собственный метод jquery, который я построил, просто чтобы упростить процесс при добавлении прослушивателя изменений к входу:

    $.fn.allchange = function (callback) {
        var me = this;
        var last = "";
        var infunc = function () {
            var text = $(me).val();
            if (text != last) {
                last = text;
                callback();
            }
            setTimeout(infunc, 100);
        }
        setTimeout(infunc, 100);
    };

Вы можете назвать это так:

$("#myInput").allchange(function () {
    alert("change!");
});
LcSalazar
источник
1
По какой-то причине для меня этот код не работает при перенаправлении страницы (когда я выхожу из приложения и перенаправляюсь на страницу входа, где происходит автозаполнение). Хотя это действительно работает при обновлении страницы.
VishwaKumar
1
это выглядит как мобильный аккумулятор батареи: /
Stefan Fisk
@StefanFisk - Не совсем так. Простого повторяющегося таймера, установленного на уровне JS страницы браузера, недостаточно, чтобы повлиять на вашу батарею, так как на большинстве веб-страниц происходит так много всего ... Вы действительно думаете, что google.com не устанавливает повторяющихся таймеров? Какой недостаток в управлении питанием был бы, если бы я мог просто запрограммировать на JS веб-страницу, которая разряжает батарею пользователя ...
LcSalazar
15

Я много читал об этой проблеме и хотел найти очень быстрое решение, которое мне помогло.

let style = window.getComputedStyle(document.getElementById('email'))
  if (style && style.backgroundColor !== inputBackgroundNormalState) {
    this.inputAutofilledByBrowser = true
  }

где inputBackgroundNormalStateдля моего шаблона это «RGB (255, 255, 255)».

Таким образом, в основном, когда браузеры применяют автозаполнение, они имеют тенденцию указывать, что ввод автоматически заполняется, применяя другой (раздражающий) желтый цвет к вводу.

Изменить: это работает для каждого браузера

DrNio
источник
Отличное мышление!
мото
7

К сожалению, единственный надежный способ проверить этот кросс-браузер - опросить ввод. Чтобы сделать его отзывчивым, также слушайте события. Chrome начал скрывать значения автозаполнения от javascript, который требует взлома.

  • Опрашивать каждые пол-трети секунды (в большинстве случаев не обязательно быть мгновенным)
  • Запустите событие изменения с помощью JQuery, затем выполните логику в функции, слушающей событие изменения.
  • Добавить исправление для скрытых значений пароля автозаполнения Chrome.

    $(document).ready(function () {
        $('#inputID').change(YOURFUNCTIONNAME);
        $('#inputID').keypress(YOURFUNCTIONNAME);
        $('#inputID').keyup(YOURFUNCTIONNAME);
        $('#inputID').blur(YOURFUNCTIONNAME);
        $('#inputID').focusin(YOURFUNCTIONNAME);
        $('#inputID').focusout(YOURFUNCTIONNAME);
        $('#inputID').on('input', YOURFUNCTIONNAME);
        $('#inputID').on('textInput', YOURFUNCTIONNAME);
        $('#inputID').on('reset', YOURFUNCTIONNAME);
    
        window.setInterval(function() {
            var hasValue = $("#inputID").val().length > 0;//Normal
            if(!hasValue){
                hasValue = $("#inputID:-webkit-autofill").length > 0;//Chrome
            }
    
            if (hasValue) {
                $('#inputID').trigger('change');
            }
        }, 333);
    });
ведро
источник
6

В github есть новый компонент polyfill для решения этой проблемы. Посмотрите на автозаполнение события . Просто нужно установить его и вуаля, автозаполнение работает как положено.

bower install autofill-event
Дэвид
источник
Это прекрасно работает с jQuery Custom Forms. Я только что добавил его, и мои собственные списки выбора отлично работали с автозаполнением.
Крис Блум
6

Мое решение:

Прослушайте changeсобытия, как обычно, и при загрузке содержимого DOM сделайте следующее:

setTimeout(function() {
    $('input').each(function() {
        var elem = $(this);
        if (elem.val()) elem.change();
    })
}, 250);

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

Камило Мартин
источник
Отлично. Первое решение, которое я нашел, работая с Chrome!
Rid Iculous
3
Это действительно @RidIculous, насколько простыми могут быть некоторые решения.
Камило Мартин
3
Но elem.val () возвращает пустую строку для полей автозаполнения в Chrome :(
Hemant_Negi
@Hemant_Negi Chrome не отправляет событие изменения в любом случае? Поправьте меня если я ошибаюсь. Я использую LastPass и слишком ленив, чтобы отключить его, чтобы увидеть, если он также работает без.
Камило Мартин
1
Да, событие изменения отправки Chrome, но, когда я пытаюсь получить значение, оно возвращается пустым.
Hemant_Negi
4

Я также столкнулся с той же проблемой, когда label не обнаруживал автозаполнение и анимация перемещения метки при заполнении текста перекрывалась, и это решение работало для меня.

input:-webkit-autofill ~ label {
    top:-20px;
} 
st0495
источник
Это полезно
rustyshackleford
Именно то, что мне было нужно :)
Dabrule
4

Я искал похожую вещь. Только Chrome ... В моем случае div обертки должен был знать, было ли заполнено поле ввода. Так что я мог бы дать ему дополнительную CSS, как это делает Chrome в поле ввода, когда он заполняется автоматически. Посмотрев на все ответы выше, мое комбинированное решение было следующим:

/* 
 * make a function to use it in multiple places
 */
var checkAutoFill = function(){
    $('input:-webkit-autofill').each(function(){
        $(this).closest('.input-wrapper').addClass('autofilled');
    });
}

/* 
 * Put it on the 'input' event 
 * (happens on every change in an input field)
 */
$('html').on('input', function() {
    $('.input-wrapper').removeClass('autofilled');
    checkAutoFill();
});

/*
 * trigger it also inside a timeOut event 
 * (happens after chrome auto-filled fields on page-load)
 */
setTimeout(function(){ 
    checkAutoFill();
}, 0);

HTML для этого будет

<div class="input-wrapper">
    <input type="text" name="firstname">
</div>
Julesezaar
источник
3

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

Чтобы сделать это, вы можете проверить, имеет ли вход (ы) значение (я) с:

$(function() {
    setTimeout(function() {
        if ($("#inputID").val().length > 0) {
            // YOUR CODE
        }
    }, 100);
});

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

S.Lund
источник
1
Этот код прекрасно работает для меня, если вы обновите третью строку до($("#inputID:-webkit-autofill").val().length > 0) {
Гектор
3

Это решение для браузеров с движком рендеринга webkit . Когда форма заполнена автоматически , входные данные получат псевдокласс : -webkit-autofill- (например, input: -webkit-autofill {...}). Так что это идентификатор, который вы должны проверить с помощью JavaScript.

Решение с некоторой формой теста:

<form action="#" method="POST" class="js-filled_check">

    <fieldset>

        <label for="test_username">Test username:</label>
        <input type="text" id="test_username" name="test_username" value="">

        <label for="test_password">Test password:</label>
        <input type="password" id="test_password" name="test_password" value="">

        <button type="submit" name="test_submit">Test submit</button>

    </fieldset>

</form>

И JavaScript:

$(document).ready(function() {

    setTimeout(function() {

        $(".js-filled_check input:not([type=submit])").each(function (i, element) {

            var el = $(this),
                autofilled = (el.is("*:-webkit-autofill")) ? el.addClass('auto_filled') : false;

            console.log("element: " + el.attr("id") + " // " + "autofilled: " + (el.is("*:-webkit-autofill")));

        });

    }, 200);

});

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

Этот код добавит класс auto_filled к заполненным входам. Кроме того, я попытался проверить значение пароля ввода или его длину, но это сработало сразу после того, как произошло какое-то событие на странице. Поэтому я попытался вызвать какое-то событие, но безуспешно. Пока это мое решение. Наслаждайтесь!

Адам Шипицкий
источник
Это актуальный ответ.
Бен Расикот
Я попробовал это решение и работал очень хорошо для меня. Большое спасибо.
Маркус Кризостомо
2

У меня есть идеальное решение для этого вопроса, попробуйте этот фрагмент кода.
Демо здесь

function ModernForm() {
    var modernInputElement = $('.js_modern_input');

    function recheckAllInput() {
        modernInputElement.each(function() {
            if ($(this).val() !== '') {
                $(this).parent().find('label').addClass('focus');
            }
        });
    }

    modernInputElement.on('click', function() {
        $(this).parent().find('label').addClass('focus');
    });
    modernInputElement.on('blur', function() {
        if ($(this).val() === '') {
            $(this).parent().find('label').removeClass('focus');
        } else {
            recheckAllInput();
        }
    });
}

ModernForm();
.form_sec {
  padding: 30px;
}
.form_sec .form_input_wrap {
  position: relative;
}
.form_sec .form_input_wrap label {
  position: absolute;
  top: 25px;
  left: 15px;
  font-size: 16px;
  font-weight: 600;
  z-index: 1;
  color: #333;
  -webkit-transition: all ease-in-out 0.35s;
  -moz-transition: all ease-in-out 0.35s;
  -ms-transition: all ease-in-out 0.35s;
  -o-transition: all ease-in-out 0.35s;
  transition: all ease-in-out 0.35s;
}
.form_sec .form_input_wrap label.focus {
  top: 5px;
  color: #a7a9ab;
  font-weight: 300;
  -webkit-transition: all ease-in-out 0.35s;
  -moz-transition: all ease-in-out 0.35s;
  -ms-transition: all ease-in-out 0.35s;
  -o-transition: all ease-in-out 0.35s;
  transition: all ease-in-out 0.35s;
}
.form_sec .form_input {
  width: 100%;
  font-size: 16px;
  font-weight: 600;
  color: #333;
  border: none;
  border-bottom: 2px solid #d3d4d5;
  padding: 30px 0 5px 0;
  outline: none;
}
.form_sec .form_input.err {
  border-bottom-color: #888;
}
.form_sec .cta_login {
  border: 1px solid #ec1940;
  border-radius: 2px;
  background-color: #ec1940;
  font-size: 14px;
  font-weight: 500;
  text-align: center;
  color: #ffffff;
  padding: 15px 40px;
  margin-top: 30px;
  display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form class="form_sec">
    <div class="row clearfix">
        <div class="form-group col-lg-6 col-md-6 form_input_wrap">
            <label>
                Full Name
            </label>
            <input type="text" name="name" id="name" class="form_input js_modern_input">
        </div>
    </div>
    <div class="row clearfix">
        <div class="form-group form_input_wrap col-lg-6 col-md-6">
            <label>
                Emaill
            </label>
            <input type="email" name="email" class="form_input js_modern_input">
        </div>
    </div>
    <div class="row clearfix">
        <div class="form-group form_input_wrap col-lg-12 col-md-12">
            <label>
                Address Line 1
            </label>
            <input type="text" name="address" class="form_input js_modern_input">
        </div>
    </div>
    <div class="row clearfix">
        <div class="form-group col-lg-6 col-md-6 form_input_wrap">
            <label>
                City
            </label>
            <input type="text" name="city" class="form_input js_modern_input">
        </div>
        <div class="form-group col-lg-6 col-md-6 form_input_wrap">
            <label>
                State
            </label>
            <input type="text" name="state" class="form_input js_modern_input">
        </div>
    </div>
    <div class="row clearfix">
        <div class="form-group col-lg-6 col-md-6 form_input_wrap">
            <label>
                Country
            </label>
            <input type="text" name="country" class="form_input js_modern_input">
        </div>
        <div class="form-group col-lg-4 col-md-4 form_input_wrap">
            <label>
                Pin
            </label>
            <input type="text" name="pincode" class="form_input js_modern_input">
        </div>
    </div>
    <div class="row cta_sec">
        <div class="col-lg-12">
            <button type="submit" class="cta_login">Submit</button>
        </div>
    </div>
</form>

Суреш Патту
источник
2

В chrome вы можете обнаружить поля автозаполнения, установив специальное правило css для автозаполненных элементов, а затем проверив с помощью javascript, применяется ли к элементу это правило.

Пример:

CSS

input:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 30px white inset;
}

JavaScript

  let css = $("#selector").css("box-shadow")
  if (css.match(/inset/))
    console.log("autofilled:", $("#selector"))
Пьетро Коэльо
источник
2

Вот CSS-решение, взятое у команды Klarna UI. Смотрите их хорошую реализацию здесь ресурс

У меня отлично работает.

input:-webkit-autofill {
  animation-name: onAutoFillStart;
  transition: background-color 50000s ease-in-out 0s;
}
input:not(:-webkit-autofill) {
  animation-name: onAutoFillCancel;
}
zdrsoft
источник
1

Я использовал это решение для той же проблемы.

HTML-код должен измениться на это:

<input type="text" name="username" />
<input type="text" name="password" id="txt_password" />

и код JQuery должен быть в document.ready:

$('#txt_password').focus(function(){
    $(this).attr('type','password');
});
a828h
источник
0

Я использовал событие размытия в имени пользователя, чтобы проверить, заполнено ли поле pwd автоматически.

 $('#userNameTextBox').blur(function () {
        if ($('#userNameTextBox').val() == "") {
            $('#userNameTextBox').val("User Name");
        }
        if ($('#passwordTextBox').val() != "") {
            $('#passwordTextBoxClear').hide(); // textbox with "Password" text in it
            $('#passwordTextBox').show();
        }
    });

Это работает для IE и должно работать для всех других браузеров (я только проверял IE)

Бриджит Аррингтон
источник
@ChrisN Я тестировал свое решение с IE, браузеры по-разному обрабатывают события javascsript. Мое решение простое и легкое для чтения, и оно предназначено для одного из самых сложных браузеров для написания кода.
Бриджит Аррингтон
1
Я в конечном итоге с тем же решением: blurсобытие. Я применяю ту же функцию для changeи blurсобытия , и он работал большой. Простое решение без лишних библиотек.
Пауло Чек
0

У меня была такая же проблема, и я написал это решение.

Он начинает опрос каждого поля ввода при загрузке страницы (я установил 10 секунд, но вы можете настроить это значение).
Через 10 секунд он прекращает опрос в каждом поле ввода и начинает опрос только на сфокусированном входе (если он есть). Он останавливается, когда вы размыте вход, и снова запускается, если вы фокусируете один.

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

// This part of code will detect autofill when the page is loading (username and password inputs for example)
var loading = setInterval(function() {
    $("input").each(function() {
        if ($(this).val() !== $(this).attr("value")) {
            $(this).trigger("change");
        }
    });
}, 100);
// After 10 seconds we are quite sure all the needed inputs are autofilled then we can stop checking them
setTimeout(function() {
    clearInterval(loading);
}, 10000);
// Now we just listen on the focused inputs (because user can select from the autofill dropdown only when the input has focus)
var focused;
$(document)
.on("focus", "input", function() {
    var $this = $(this);
    focused = setInterval(function() {
        if ($this.val() !== $this.attr("value")) {
            $this.trigger("change");
        }
    }, 100);
})
.on("blur", "input", function() {
    clearInterval(focused);
});

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

Что-то вроде:

// This part of code will detect autofill when the page is loading (username and password inputs for example)
var loading = setInterval(function() {
    $("input").each(function() {
        if ($(this).val() !== $(this).attr("value")) {
            $(this).trigger("change");
        }
    });
}, 100);
// After 10 seconds we are quite sure all the needed inputs are autofilled then we can stop checking them
setTimeout(function() {
    clearInterval(loading);
}, 10000);
// Now we just listen on inputs of the focused form
var focused;
$(document)
.on("focus", "input", function() {
    var $inputs = $(this).parents("form").find("input");
    focused = setInterval(function() {
        $inputs.each(function() {
            if ($(this).val() !== $(this).attr("value")) {
                $(this).trigger("change");
            }
        });
    }, 100);
})
.on("blur", "input", function() {
    clearInterval(focused);
});
Фес Враста
источник
0

Если вы хотите только определить, использовалось ли автоматическое заполнение или нет, а не точно определить, когда и в каком поле использовалось автоматическое заполнение, вы можете просто добавить скрытый элемент, который будет заполняться автоматически, а затем проверить, содержит любое значение. Я понимаю, что это может быть не тем, что интересует многих. Установите поле ввода с отрицательным индексом tabIndex и с абсолютными координатами далеко за пределами экрана. Важно, чтобы входные данные были частью той же формы, что и остальные входные данные. Вы должны использовать имя, которое будет выбрано автоматическим заполнением (например, «второе имя»).

var autofilldetect = document.createElement('input');
autofilldetect.style.position = 'absolute';
autofilldetect.style.top = '-100em';
autofilldetect.style.left = '-100em';
autofilldetect.type = 'text';
autofilldetect.name = 'secondname';
autofilldetect.tabIndex = '-1';

Добавьте этот ввод в форму и проверьте его значение при отправке формы.

bornSwift
источник
0

Там же , как представляется, решение к этому , что не опирается на опрос (по крайней мере , для Chrome). Это почти так же хакерски, но я думаю, что немного лучше, чем глобальный опрос.

Рассмотрим следующий сценарий:

  1. Пользователь начинает заполнять поле1

  2. Пользователь выбирает предложение автозаполнения, которое автоматически заполняет field2 и field3

Решение: Зарегистрируйте onblur во всех полях, который проверяет наличие автоматически заполненных полей с помощью следующего фрагмента jQuery $ (': - webkit-autofill')

Это не будет немедленным, так как оно будет отложено до тех пор, пока пользователь не размывает поле field1, но оно не зависит от глобального опроса, поэтому IMO - это лучшее решение.

Тем не менее, поскольку нажатие клавиши ввода может отправить форму, вам также может понадобиться соответствующий обработчик для onkeypress.

Кроме того, вы можете использовать глобальный опрос для проверки $ (': - webkit-autofill')

Дэн Д
источник
0

Исходя из моего личного опыта, приведенный ниже код хорошо работает с Firefox IE и Safari, но не очень хорошо работает при выборе автозаполнения в Chrome.

function check(){
clearTimeout(timeObj);
 timeObj = setTimeout(function(){
   if($('#email').val()){
    //do something
   }
 },1500);
}

$('#email').bind('focus change blur',function(){
 check();
});

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

$('#email').bind('click', function(){
 check();
});
Роджер
источник
0

Мне удалось на хром с:

    setTimeout(
       function(){
          $("#input_password").focus();
          $("#input_username").focus();
          console.log($("#input_username").val());
          console.log($("#input_password").val());
       }
    ,500);
Антуан О
источник
Не уверен, когда именно запустится автозаполнение Chrome, но в $ ('input, select'). On ('focusin', function (evt) {...}); Я получаю автозаполненные значения для всех полей уже.
Мирек
Новая версия может быть?
Антуан О
0

Мое решение:

    $.fn.onAutoFillEvent = function (callback) {
        var el = $(this),
            lastText = "",
            maxCheckCount = 10,
            checkCount = 0;

        (function infunc() {
            var text = el.val();

            if (text != lastText) {
                lastText = text;
                callback(el);
            }
            if (checkCount > maxCheckCount) {
                return false;
            }
            checkCount++;
            setTimeout(infunc, 100);
        }());
    };

  $(".group > input").each(function (i, element) {
      var el = $(element);

      el.onAutoFillEvent(
          function () {
              el.addClass('used');
          }
      );
  });
Romick
источник
Объяснение вашего решения поможет
тонна
Я думал, что это было очевидно. В общем, идея состоит в том, чтобы проверить значение поля ввода пару раз. В текущей реализации это 10 раз с задержкой 100 мс. Поэтому, когда во время второго браузера 10 * 1000 = 1 с заполняется значение автозаполнения, вызывается обратный вызов, переданный автозаполнению. В текущем примере это просто добавляет класс. Если у вас есть еще вопросы, пожалуйста, не стесняйтесь, а просто спросите :).
Ромик
0

После исследования проблема заключается в том, что браузеры webkit не запускают событие change при автозаполнении. Мое решение состояло в том, чтобы получить класс автозаполнения, который добавляет webkit, и инициировать событие изменения самостоятельно.

setTimeout(function() {
 if($('input:-webkit-autofill').length > 0) {
   //do some stuff
 }
},300)

Вот ссылка на выпуск хрома. https://bugs.chromium.org/p/chromium/issues/detail?id=636425

Цветан Химчев
источник
0

Например, чтобы обнаружить электронную почту, я пытался «при изменении» и наблюдателя мутаций, ни один не работал. setInterval хорошо работает с автозаполнением LinkedIn (не раскрывая весь мой код, но вы поняли идею) и хорошо работает с бэкэндом, если вы добавите здесь дополнительные условия для замедления AJAX. И если нет никаких изменений в поле формы, например, если они не набирают текст для редактирования своей электронной почты, lastEmail предотвращает бессмысленные эхо-запросы AJAX.

// lastEmail needs scope outside of setInterval for persistence.
var lastEmail = 'nobody';
window.setInterval(function() { // Auto-fill detection is hard.
    var theEmail = $("#email-input").val();
    if (
        ( theEmail.includes("@") ) &&
        ( theEmail != lastEmail )
    ) {
        lastEmail = theEmail;
        // Do some AJAX
    }
}, 1000); // Check the field every 1 second
Пи Джей Брюнет
источник
0

Мне было трудно обнаружить автозаполнение в Firefox. Это единственное решение, которое сработало для меня:

демонстрация

HTML:

<div class="inputFields">
   <div class="f_o">
      <div class="field_set">
        <label class="phold">User</label>
        <input type="tel" class="form_field " autocomplete="off" value="" maxlength="50">
      </div>
   </div>
   <div class="f_o">
      <div class="field_set">
         <label class="phold">Password</label>
         <input type="password" class="form_field " autocomplete="off" value="" maxlength="50">
      </div>
   </div>
</div>

CSS:

/* Detect autofill for Chrome */
.inputFields input:-webkit-autofill {
    animation-name: onAutoFillStart;
    transition: background-color 50000s ease-in-out 0s;
}
.inputFields input:not(:-webkit-autofill) {
    animation-name: onAutoFillCancel;
}

@keyframes onAutoFillStart {
}

@keyframes onAutoFillCancel {
}
.inputFields {
  max-width: 414px;
}

.field_set .phold{
  display: inline-block;
  position: absolute;
  font-size: 14px;
  color: #848484;
  -webkit-transform: translate3d(0,8px,0);
  -ms-transform: translate3d(0,8px,0);
  transform: translate3d(0,8px,0);
  -webkit-transition: all 200ms ease-out;
  transition: all 200ms ease-out;
  background-color: transparent;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  margin-left: 8px;
  z-index: 1;
  left: 0;
  pointer-events: none;
}

.field_set .phold_active {
   font-size: 12px;
   -webkit-transform: translate3d(0,-8px,0);
  -ms-transform: translate3d(0,-8px,0);
  transform: translate3d(0,-8px,0);
  background-color: #FFF;
  padding-left: 3px;
  padding-right: 3px;
}

.field_set input[type='text'], .field_set select, .field_set input[type='tel'], .field_set input[type='password'] {
    height: 36px;
}

.field_set input[type='text'], .field_set input[type='tel'], .field_set input[type='password'], .field_set select, .field_set textarea {
    box-sizing: border-box;
    width: 100%;
    padding: 5px;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    border: 1px solid #ababab;
    border-radius: 0;
}

.field_set {
    margin-bottom: 10px;
    position: relative;
}

.inputFields .f_o {
    width: 100%;
    line-height: 1.42857143;
    float: none;
}

JavaScript:

    // detect auto-fill when page is loading
  $(window).on('load', function() {
    // for sign in forms when the user name and password are filled by browser
    getAutofill('.inputFields');
  });

  function getAutofill(parentClass) {
    if ($(parentClass + ' .form_field').length > 0) {    
      var formInput = $(parentClass + ' .form_field');
      formInput.each(function(){   
        // for Chrome:  $(this).css('animation-name') == 'onAutoFillStart'
        // for Firefox: $(this).val() != ''
        if ($(this).css('animation-name') == 'onAutoFillStart' || $(this).val() != '') {
          $(this).siblings('.phold').addClass('phold_active');
        } else {
          $(this).siblings('.phold').removeClass('phold_active');
        }
      });
    }
  } 

  $(document).ready(function(){

    $(document).on('click','.phold',function(){
      $(this).siblings('input, textarea').focus();
    });
    $(document).on('focus','.form_field', function(){
      $(this).siblings('.phold').addClass('phold_active');
    });

    // blur for Chrome and change for Firefox
    $(document).on('blur change','.form_field', function(){
      var $this = $(this);
      if ($this.val().length == 0) {        
        $(this).siblings('.phold').removeClass('phold_active');
      } else {
        $(this).siblings('.phold').addClass('phold_active');
      }
    });

    // case when form is reloaded due to errors
    if ($('.form_field').length > 0) {
      var formInput = $('.form_field');
      formInput.each(function(){
        if ($(this).val() != '') {
          $(this).siblings('.phold').addClass('phold_active');
        } else {
          $(this).siblings('.phold').removeClass('phold_active');
        }
      });
    }

  }); 

Для Chrome я использую: if ($(this).css('animation-name') == 'onAutoFillStart')

Для Firefox: if ($(this).val() != '')

Serj
источник
-2

попробуй в CSS

input:-webkit-autofill { border-color: #9B9FC4 !important; }

Schwarzkopf
источник