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


165

Як визначити, чи веб-переглядач автоматично заповнив текстове поле? Особливо з полями імені користувача та паролем, які автоматично заповнюються під час завантаження сторінки.

Перше моє запитання - коли це відбувається в послідовності завантаження сторінки? Це перед документом або після нього вже?

По-друге, як я можу використовувати логіку, щоб дізнатися, чи це сталося? Це не те, що я хочу, щоб це не відбувалося, а просто зачепитися за подію. Переважно щось подібне:

if (autoFilled == true) {

} else {

}

Якщо можливо, я хотів би побачити jsfiddle, що показує вашу відповідь.

Можливі дублікати

Подія DOM для автозаповнення пароля браузера?

Автозаповнення браузера та Javascript запускаються подіями

- Настільки, що ці питання насправді не пояснюють, які події викликаються, вони просто постійно перевіряють текстове поле (не добре для продуктивності!).


1
Перевірка займає декілька мікросекунд, тоді як інтервал буде справляти перевірку кожні 100 мілісекунд або близько того ... як це взагалі вплине на продуктивність? Якби існувала подія, запущена браузером, я впевнений, що вони використали б її.
Есаїлія

Я бачу, що ви маєте на увазі, але це залежить від першої частини мого питання, чи JavaScript навіть знає, що щойно відбулася зміна (наприклад, перед document.ready)
Не визначено

1
НАЙКРАЩЕ рішення для Chrome / WebKit полягає у використанні селектора DOM: document.querySelectorAll ('input: -webkit-autoofill'); після невеликої затримки 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" заповнення форми або опитування через регулярний інтервал, щоб побачити, чи заповнено її.

Що стосується вашого запитання, чи заповнений він перед документом чи раніше, він знову варіюється від браузера до браузера і навіть від версії до версії. Для полів імені користувача / пароля лише тоді, коли ви вибрали поле для пароля користувача. Таким чином, у вас буде дуже безладний код, якщо ви спробуєте долучитися до будь-якої події.

Ви можете прочитати це ТУТ


26
Зауважте, є різниця між автозаповненням та автозаповненням. ОП конкретно стосується браузерів, які заповнюють збережені дані для входу при завантаженні сторінки.
Роберт

2
Звичайний хак - це мусент на якійсь важливій частині сторінки. Подія спрацьовує, коли миша користувачем головує на кнопку чи щось подібне.
Брайс

1
@Bryce Особисто я пішов би з подією "розмиття" через те, що автозаповнення є тим, що відбувається після того, як ви ввійдете в область введення. Очевидно, що це не ідеально, але як резервна копія для перелічених вище браузерів може бути дуже корисною
JakeJ

Не забувайте про inputподію. Ось що Chrome запускається при автоматичному заповненні (і, можливо, також автозаповнення, якщо в Chrome є таке, я завжди вимикаю цей матеріал).
TJ Crowder

Дивіться мою відповідь в одному рядку, якщо ви просто хочете дізнатись, чи значення в текстовому полі заповнено автозаповненням Google chrome.
ThdK

71

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

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

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

Ми можемо визначити правило css для недійсного переходу для потрібного <input>елемента після його :-webkit-autofillредагування. Тоді JS зможе причепити доanimationstart події.

Подяки команди Klarna UI . Дивіться їхню приємну реалізацію тут:


1
це, безумовно, найкраще рішення! Кудо до Лева тут для цього. Дякуємо, що поділилися рішенням KI-інтерфейсу Klarna ... більше нічого не працювало для мене, поки я не знайшов цього. Рятувальник життя!
Бреден Роквелл Нап'єр

1
Так само , як CSS управляє ключовими кадрами тут github.com/klarna/ui/blob/v4.10.0/Field/styles.scss#L181-L189 також необхідні
user1069816

Це спрацювало бездоганно для мене! Потрібно трохи пограти з нею, щоб з’ясувати точний підхід. Дякую команді Klarna
pritesh

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
Не працює над хромом, як і 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
Це виглядає як досить мобільний акумулятор: /
Стефан Фіск,

@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 є новий компонент поліфіл. Погляньте на автозаповнення події . Потрібно просто встановити його і voilà, автозаповнення працює як очікувалося.

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
Так, подія зміни хромової відправки, але, коли я намагаюся отримати значення, воно повертається порожнім.
Hemant_Negi

4

Я також зіткнувся з тією ж проблемою, коли мітка не виявила автозаповнення, а анімація для переміщення мітки на тексті заповнення перекривалась, і це рішення працювало на мене.

input:-webkit-autofill ~ label {
    top:-20px;
} 

Це корисно.
rustyshackleford

Саме те, що мені було потрібно :)
Дабруле

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- (fe 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

Щодо хромування, ви можете виявити поля автозаповнення, встановивши спеціальне правило 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

Якщо ви хочете лише визначити, використовувалося чи ні, автоматично замість того, щоб точно визначити, коли і до якого поля використовується автозаповнення, ви можете просто додати прихований елемент, який буде автоматично заповнений, а потім перевірити, чи це містить будь-яке значення. Я розумію, що це може бути не тим, що цікавить багатьох людей. Встановіть поле введення за допомогою негативної вкладкиIndex і з абсолютними координатами добре вимкнено екран. Важливо, щоб вхід був частиною тієї ж форми, що й решта вводу. Потрібно використовувати ім'я, яке буде підхоплено автоматичним заповненням (наприклад, "ім'я другого").

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. Користувач вибирає пропозицію про автозаповнення, яка автоматично заповнює поля2 та поле3

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

Це не буде негайним, оскільки буде відкладено, поки користувач не розмиває поле1, але він не покладається на глобальне опитування, так що IMO, це краще рішення.

Однак, якщо натиснути клавішу введення, можна надіслати форму, вам може знадобитися відповідний обробник для onkeypress.

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


0

З мого особистого досвіду, наведений нижче код добре працює з Firefox IE та сафарі, але не дуже добре підбирає автозаповнення в хромі.

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) {...}); Я вже отримую автоматично заповнені значення для всіх полів.
mirek

Можливо, нова версія?
Антуан О

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 не запускають подію зміни на автозаповнення. Моє рішення полягало в тому, щоб отримати клас автозаповнення, який додає webkit і викликати подія зміни власноруч.

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

Ось посилання на проблему з хромом. https://bugs.chromium.org/p/chromium/isissue/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.