ブラウザの自動入力の検出


165

ブラウザーがテキストボックスに自動入力したかどうかはどのようにしてわかりますか?特に、ページの読み込み時に自動入力されるユーザー名とパスワードのボックスで。

私の最初の質問は、これがページ読み込みシーケンスでいつ発生するかです。document.readyの前ですか後ですか?

次に、ロジックを使用してこれが発生したかどうかを確認するにはどうすればよいですか?これが発生しないようにするために、イベントにフックするだけではありません。できればこのようなもの:

if (autoFilled == true) {

} else {

}

できれば、答えを表示するjsfiddleを見たいと思います。

可能な重複

ブラウザのパスワード自動入力のDOMイベント?

ブラウザの自動入力とJavaScriptによってトリガーされるイベント

-これらの質問はどちらも、どのイベントがトリガーされるかを実際に説明するものではなく、テキストボックスを継続的に再確認するだけです(パフォーマンスには適していません)。


1
チェックには数マイクロ秒かかりますが、間隔は100ミリ秒ごとにチェックを実行するので、パフォーマンスにどのように影響しますか?ブラウザによって発火されたイベントが存在した場合、彼らはそれを使用したはずです。
エサイリヤ2012

どういう意味かはわかりますが、JavaScriptが変更が行われたことを認識しているかどうか(たとえば、document.readyの前)の質問の最初の部分によって異なります
未定義

1
Chrome / WebKitの最良のソリューションは、DOMセレクターを使用することです。document.querySelectorAll( 'input:-webkit-autofill'); 少し遅れてsetTimeout(... code here ... 250);
ChrisN

基本的に、自動入力されたユーザーを自動ログインしたいのですが、自動的にログアウトしたときに、迷惑なotログインが必要です。
Muhammad Umer 2016年

@ChrisNあなたのコメントは実際に私に(シンプルな)解決策を与えたものです。私はそれを答えとは思わない!1つとして投稿し、pingを送信して、感謝の意を表してください。
イーサンカミンスキー

回答:


123

問題は、ブラウザによってオートフィルの処理が異なることです。一部は変更イベントを送出し、一部は送出しません。したがって、ブラウザが入力フィールドを自動補完するときにトリガーされるイベントにフックすることはほとんど不可能です。

  • 異なるブラウザーのイベントトリガーを変更します。

    • ユーザー名/パスワードフィールド:

      1. Firefox 4、IE 7、IE 8はchangeイベントを送出しません。
      2. Safari 5とChrome 9はchangeイベントを送出します。
    • その他のフォームフィールドの場合:

      1. IE 7とIE 8はchangeイベントを送出しません。
      2. Firefox 4は、ユーザーが提案のリストから値を選択し、フィールドからタブを外したときに、change changeイベントを送出します。
      3. Chrome 9は変更イベントを送出しません。
      4. Safari 5はchangeイベントを送出します。

最良のオプションは、フォームで使用autocomplete="off"しているフォームのオートコンプリートを無効にするか、定期的にポーリングして、フォームが入力されているかどうかを確認することです。

document.readyの前または前に記入されているかどうかについての質問については、ブラウザーによって、さらにはバージョンごとに異なります。ユーザー名を選択した場合のみ、ユーザー名/パスワードフィールドのパスワードフィールドが入力されます。したがって、イベントにアタッチしようとすると、非常に厄介なコードになります。

こちらでよく読んでください


26
オートコンプリートとオートフィルには違いがあることに注意してください。OPは、ページのロード時に保存されたログインの詳細を入力するブラウザーを具体的に指します。
ロバート2013

2
通常のハックは、ページのいくつかの重要な部分のmousenterです。イベントは、ユーザーのマウスがボタンなどに向かっているときにトリガーされます。
ブライス

1
@Bryce個人的には、入力領域に入った後にオートフィルが発生するため、「ぼかし」イベントを使用します。明らかにそれは理想的ではありませんが、上記のブラウザーのフォールバックとして非常に役立つ可能性があります
JakeJ

inputイベントをお忘れなく。これが、オートコンプリートでChromeが起動するものです(Chromeにオートフィルがある場合は、おそらくオートフィルもそうです。私は常にこれをオフにします)。
TJクラウダー2014

テキストボックスの値がgoogle chromeオートコンプリートによって入力されたかどうかを知りたい場合は、1行の回答を参照してください。
ThdK 2016年

70

WebKitブラウザーのソリューション

:-webkit-autofill CSS疑似クラスのMDNドキュメントから:

:-webkit-autofill CSS擬似クラスは、要素がブラウザによって自動入力された値を持つ場合に一致します

edした後、目的の要素にvoid 遷移 cssルールを定義できます。JSはイベントにフックできます。<input>:-webkit-autofillanimationstart

Klarna UIチームの功績。ここで彼らの素晴らしい実装を見てください:


1
これは断然、最善の解決策です!これをここでレフに称賛してください。Klarna UIのソリューションを共有していただきありがとうございます。これが見つかるまで、他には何もうまくいきませんでした。ライフセーバー!
Braden Rockwell Napier

1
CSSルールに加えて、こちらのキーフレームgithub.com/klarna/ui/blob/v4.10.0/Field/styles.scss#L181-L189も必要です
user1069816

これは完璧に機能しました!正確なアプローチを理解するには、少し遊んでみる必要があります。Klarnaチームに感謝します
プリテッシュ2018

18

これは、最新のFirefox、Chrome、およびEdgeで動作します。

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

6
'input'!これが最も簡単な解決策でしたが、オートコンプリートではなく、オートコンプリートのみをテストしました。
GreenRaccoon23

オートコンプリートアドオンでぼかしが機能しない
パスファインダー'28

入力はキーを押すたびにトリガーされます。サーバー呼び出しを行うと、頻繁にトリガーされる場合があります。
RiZKiT 2017年

素晴らしい解決策!このイベントの組み合わせにより、ユーザーによる入力とブラウザによる自動入力の問題が解決されます。
PetrHladík18年

17

グーグルクロムオートコンプリートの場合、これは私のために働きました:

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

それも私のために働いた。私は何百ものソリューションを試しましたが、誰もうまくいきませんでした。どうもありがとうございました。一日を節約し、解決策を模索していたすべての時間を節約してください。
ペロッツォ2018

4
このアプローチではエラーが発生します:他のブラウザーで「構文エラー、認識されない式:サポートされていない疑似:-webkit-autofill」(Firefoxで試した)
anvita surapaneni

1
2020年と同様にChromeで動作せず、認識されない式のエラーもスローされます:サポートされていない疑似:-webkit-autofill
Leo

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-実際にはそうではありません。ほとんどのWebページ内にそんなに起こっているようブラウザのページのJSレベルでの単純な繰り返しタイマー設定は、あなたが本当に考えて....、あなたのバッテリーへの影響には十分ではありませんgoogle.comは何の再発タイマーを設定していませんか?ユーザーのバッテリーを消耗させるWebページを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から自動入力値を非表示にし始めました。

  • 0.5秒から3秒ごとにポーリングする(ほとんどの場合、即時である必要はありません)
  • 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コンポーネントがあります。autofill-eventご覧ください。ただそれをインストールしてボイラする必要があります、オートフィルは期待通りに機能します。

bower install autofill-event

これはjQuery Custom Formsでうまく機能しました。私はそれをドロップインしただけで、私のカスタム選択リストはオートフィルでうまく機能しました。
Chris Bloom

6

私の解決策:

change通常どおりイベントをリッスンし、DOMコンテンツのロード時に次のようにします。

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

これにより、ユーザーが編集する前に空でないすべてのフィールドの変更イベントが発生します。


完璧です。Chromeで動作することがわかった最初のソリューション!
Iculous 2015

3
@RidIculousは、いくつかのソリューションがいかにシンプルかを示しています。
Camilo Martin、

3
しかしelem.val()は、Chromeの自動入力されたパスワードフィールドに空の文字列を返します:(
Hemant_Negi

@Hemant_NegiとにかくChromeは変更イベントを送出しませんか?私が間違っている場合は修正してください。私はLastPassを使用していますが、怠惰すぎて無効にできないので、それがなくても機能するかどうかを確認できます。
Camilo Martin

1
はい、Chromeディスパッチ変更イベントですが、値を取得しようとすると、空が返されます。
Hemant_Negi

4

また、ラベルが自動入力を検出せず、テキストの塗りつぶしでラベルを移動するアニメーションが重複していたという同じ問題にも直面しましたが、この解決策は私にとってうまくいきました。

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

これは役に立ちます。
rustyshackleford

まさに私が必要としたもの:)
Dabrule

4

同じようなものを探していました。Chromeのみ...私の場合、ラッパーdivは入力フィールドが自動入力されたかどうかを知る必要がありました。そのため、Chromeが入力フィールドを自動入力するときに入力フィールドで行うように、CSSを追加できます。上記のすべての答えを見ると、私の組み合わせたソリューションは次のとおりでした。

/* 
 * 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
このコードは、3行目を($("#inputID:-webkit-autofill").val().length > 0) {
Hector

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クラスを塗りつぶされた入力に追加します。また、入力タイプのパスワード値または長さを確認しようとしましたが、ページで何らかのイベントが発生した直後に機能しました。だから私はいくつかのイベントをトリガーしようとしましたが、成功しませんでした。今のところ、これが私の解決策です。楽しい!


これが最新の答えです。
Ben Racicot

私はこの解決策を試してみましたが、とてもうまくいきました。どうもありがとうございました。
Marcus Crisostomo

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

以下は、Klarna UIチームから取得したCSSソリューションです。ここで彼らの素晴らしい実装を参照してくださいリソース

私にとってはうまくいきます。

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

ユーザー名のblurイベントを使用して、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つに対応しています。
Bridget Arrington、2015

1
私は同じ解決策で終わる:blurイベント。changeand blurイベントにも同じ関数を適用しましたが、うまくいきました。追加のライブラリなしのシンプルなソリューション。
Paulo Check

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を設定し、絶対座標を画面から十分に離してください。入力が残りの入力と同じフォームの一部であることが重要です。自動入力で取得される名前を使用する必要があります(「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';

この入力をフォームに追加し、フォームの送信時にその値を確認します。


0

そこ(少なくとも、Chromeの)ポーリングに依存しないこれに対する解決策のように見えます。それはほとんどハックですが、私は世界的な投票よりわずかに優れていると思います。

次のシナリオを検討してください。

  1. ユーザーがフィールド1の入力を開始します

  2. ユーザーはフィールド2とフィールド3を自動入力するオートコンプリートの候補を選択します

解決策:次のjQueryスニペット$( ':-webkit-autofill')を介して自動入力フィールドの存在をチェックするすべてのフィールドにonblurを登録します

ユーザーがフィールド1をぼかすまで遅延されるため、これはすぐには行われませんが、グローバルポーリングに依存しないため、IMOはより良いソリューションです。

つまり、Enterキーを押すとフォームを送信できるため、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){...}); すべてのフィールドの自動入力値をすでに受け取っています。
mirek

多分新しいバージョン?
アントワーヌO

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

あなたのソリューションのための説明が役立つだろう
トン

明らかにそうだと思いました。したがって、基本的には、入力フィールドの値を数回チェックするという考えです。現在の実装では、遅延は100ミリ秒で10回です。したがって、2番目の10 * 1000 = 1秒のブラウザーが自動入力値を入力すると、自動入力に渡されるコールバックが呼び出されます。現在の例では、クラスを追加するだけです。さらに質問がある場合は、ためらわずに質問してください:)。
Romick

0

調査後の問題は、Webkitブラウザーがオートコンプリートで変更イベントを起動しないことです。私の解決策は、webkitが追加するautofillクラスを取得し、変更イベントを自分でトリガーすることでした。

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 pingを防ぎます。

// 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() != '')


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.