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

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

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

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

if (autoFilled == true) {

} else {

}

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

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

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

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

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

26 ответов


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

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

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

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

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

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

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

вы можете иметь хорошее чтение на этом здесь


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

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

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

мы можем определить пустоту переход css правило на желаемый <input> элемент после :-webkit-autofilled. Затем JS сможет подключиться к animationstart событие.

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


на всякий случай, если кто-то ищет решение (как и сегодня), чтобы прослушать изменение автозаполнения браузера, вот пользовательский метод 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!");
});

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

$('#email').on('blur input', function() {
    ....
});

для автозаполнения google chrome это сработало для меня:

if ($("#textbox").is(":-webkit-autofill")) 
{    
    // the value in the input field of the form was filled in with google chrome autocomplete
}

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

bower install autofill-event

к сожалению, единственный надежный способ проверить этот кросс-браузер-это опросить входные данные. Чтобы сделать его отзывчивым, также слушайте события. 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);
    });
    

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

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

здесь inputBackgroundNormalState для моего шаблона " rgb (255, 255, 255)".

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

Edit: он будет работать для каждого браузера


мое решение:

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

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

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


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

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>

в 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"))

Я искал подобную вещь. Хром только... В моем случае обертка 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>

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

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

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

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


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

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

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

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

я использовал событие размытия для имени пользователя, чтобы проверить, было ли поле 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)


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

он начинает опрос на каждом поле ввода при загрузке страницы (я установил 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);
});

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

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

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


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

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

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

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

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

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

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

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


попробуйте в CSS

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


по моему личному опыту, приведенный ниже код хорошо работает с 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();
});

мне удалось на chrome с:

    setTimeout(
       function(){
          $("#input_password").focus();
          $("#input_username").focus();
          console.log($("#input_username").val());
          console.log($("#input_password").val());
       }
    ,500);

мое решение:

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

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

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

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


это решение для браузеров с webkit render engine. Когда форма будет заполнена автоматически, входные данные получат псевдо-класс : - webkit-автозаполнение - (f.e. вход: - webkit-автозаполнение {...}). Таким образом, это идентификатор, который вы должны проверить с помощью 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 к заполненным входам. Кроме того, я попытался проверить значение пароля типа ввода или длину, но он работал сразу после некоторого события на странице. Поэтому я попытался вызвать какое-то событие, но безуспешно. Пока это мое решение. Наслаждайтесь!


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

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

input:-webkit-autofill {
  animation-name: onAutoFillStart;
  transition: background-color 50000s ease-in-out 0s;
}
input:not(:-webkit-autofill) {
  animation-name: onAutoFillCancel;
}