213

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

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

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

if (autoFilled == true) {

} else {

}

可能であれば、あなたの答えを示すjsfiddleを見たいです。

重複の可能性

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

ブラウザのオートフィルと Javascript によってトリガーされるイベント

-- これらの質問は両方とも、どのイベントがトリガーされるかを実際に説明するものではなく、テキスト ボックスを継続的に再チェックするだけです (パフォーマンスには良くありません!)。

4

37 に答える 37

143

問題は、オートフィルの処理がブラウザによって異なることです。change イベントをディスパッチするものもあれば、ディスパッチしないものもあります。そのため、ブラウザーが入力フィールドをオートコンプリートしたときにトリガーされるイベントにフックすることはほとんど不可能です。

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

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

      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 は change イベントを送出しません。
      4. Safari 5 は change イベントを送出します。

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

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

ここでこれについてよく読むことができます

于 2012-07-29T15:07:47.180 に答える
98

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

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

:-webkit-autofill CSS 疑似クラスは、要素の値がブラウザーによって自動入力されている場合に一致します。

目的の要素が編集されたら、その要素に void遷移css ルールを定義できます。その後、JS はイベントにフックできるようになります。<input>:-webkit-autofillanimationstart

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

于 2017-01-08T06:35:59.627 に答える
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!");
});
于 2014-08-19T21:14:38.687 に答える
10

また、ラベルがオートフィルを検出せず、テキストを埋める上でラベルを移動するアニメーションが重なるという同じ問題に直面し、この解決策がうまくいきました。

input:-webkit-autofill ~ label {
    top:-20px;
} 
于 2018-05-12T15:15:36.373 に答える
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>
于 2018-06-02T12:14:03.380 に答える
3

これが古いスレッドであることは知っていますが、多くの人がここで解決策を見つけるようになると想像できます。

これを行うには、入力に値があるかどうかを次のように確認できます。

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

送信ボタンを有効にするためにロードされたときに、ログインフォームの値をチェックするためにこれを自分で使用します。コードは jQuery 用に作成されていますが、必要に応じて簡単に変更できます。

于 2014-04-10T21:15:20.927 に答える
2

In Chrome and Edge (2020) checking for :-webkit-autofill will tell you that the inputs have been filled. However, until the user interacts with the page in some way, your JavaScript cannot get the values in the inputs.

Using $('x').focus() and $('x').blur() or triggering a mouse event in code don't help.

See https://stackoverflow.com/a/35783761/32429

于 2020-08-21T22:55:02.720 に答える
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);
});
于 2014-10-24T08:43:27.640 に答える
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 のみを確認しました)。

于 2014-04-29T22:39:37.073 に答える
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');
          }
      );
  });
于 2017-06-20T11:39:02.193 に答える
0

angularjsの実用的なソリューションを見つけました。

トリックは、ディレクティブがフィールドがブラウザによって自動入力によって入力されたことを検出したときに、入力フィールドから必須プロパティを無効にすることです。

入力フィールドが不要になったため、ログイン送信ボタンが有効になりました。

これは、ユーザーがウィンドウの本体をクリックしなくても機能します ( Chrome Autofill/Autocomplete no value for password を参照)。

指令:

angular.module('formtools').directive('autofill', [
        '$interval', function ($interval)
        {
            return {
                scope: false,
                require: 'autofill',
                controller: function AutoFillController(){
                    this.applied = false;
                },
                controllerAs: 'autoFill',
                link: function (scope, elem, attrs, autofill)
                {
                    var refresh = $interval(function() {
                        // attention: this needs jquery, jqlite from angular doesn't provide this method
                        if(elem.is(':-webkit-autofill'))
                        {
                            autofill.applied = true;
                            $interval.cancel(refresh);
                        }
                    }, 100, 100);
                }
            }
        }]);

HTML:

<form name="loginform">

  <input 
     type="text" 
     name="username" 
     autofill 
     ng-required="!autoFill.applied">
  
  <input 
     type="password" 
     name="password" 
     autofill 
     ng-required="!autoFill.applied">
     
  <button ng-disabled="loginform.$invalid">Login</button>   
</form>
于 2021-12-03T14:13:28.693 に答える