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


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

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

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

if (autoFilled == true) {

} else {

}

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

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

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

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

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

26 119

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

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

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

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

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

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

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

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

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