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


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

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


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
}

Это сработало и для меня. Я пробовал сотни решений, и никто не работал. Большое спасибо, спаси мой день и все время, пока я искал решение.
— 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!");
});

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)».

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

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


Отличное мышление!
— мото

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;
} 

Это полезно
— 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>

3

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

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

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

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


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;
}

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');
});

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';

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


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');
          }
      );
  });

Объяснение вашего решения поможет
— тонна

Я думал, что это было очевидно. В общем, идея состоит в том, чтобы проверить значение поля ввода пару раз. В текущей реализации это 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() != '')


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.