Programing

브라우저 자동 완성 감지

lottogame 2020. 6. 17. 20:27
반응형

브라우저 자동 완성 감지


브라우저가 텍스트 상자를 자동으로 채웠는지 어떻게 알 수 있습니까? 특히 페이지로드를 자동으로 채우는 사용자 이름 및 비밀번호 상자가 있습니다.

첫 번째 질문은 언제 페이지로드 순서에서 발생합니까? document.ready 전후에 있습니까?

둘째, 논리를 사용하여 이것이 발생했는지 어떻게 알 수 있습니까? 나는 이것이 발생하는 것을 막고 싶지 않다. 단지 이벤트에 연결하십시오. 바람직하게는 다음과 같습니다.

if (autoFilled == true) {

} else {

}

가능하다면 귀하의 답변을 보여주는 jsfiddle을보고 싶습니다.

가능한 중복

브라우저 비밀번호 자동 완성에 대한 DOM 이벤트?

브라우저 자동 완성 및 자바 스크립트 트리거 이벤트

-이 질문들은 실제로 어떤 이벤트가 트리거되는지 설명하지는 않지만 텍스트 상자를 지속적으로 다시 확인합니다 (성능에 좋지 않음).


문제는 자동 완성 기능이 브라우저마다 다르게 처리된다는 것입니다. 일부는 변경 이벤트를 전달하지만 일부는 변경 이벤트를 전달하지 않습니다. 따라서 브라우저가 입력 필드를 자동 완성 할 때 트리거되는 이벤트에 연결하는 것은 거의 불가능합니다.

  • 다른 브라우저에 대한 이벤트 트리거 변경 :

    • 사용자 이름 / 비밀번호 필드의 경우 :

      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"하거나 정기적으로 폴링하여 양식이 채워져 있는지 확인하는 것입니다.

문서가 채워져 있는지 또는 document.ready 전에 채워지는지에 대한 질문은 브라우저마다, 버전마다 다릅니다. 사용자 이름 / 암호 필드의 경우 사용자 이름 암호 필드를 선택한 경우에만 채워집니다. 따라서 모든 이벤트에 첨부하려고하면 매우 지저분한 코드가 생깁니다.

여기 에서 잘 읽을 수 있습니다.


WebKit 브라우저를위한 솔루션

: -webkit-autofill CSS 의사 클래스에 대한 MDN 문서에서 :

: -webkit-autofill CSS 의사 클래스는 요소가 브라우저에서 자동으로 값을 채울 때 일치합니다.

원하는 요소 대해 void 전환 CSS 규칙을 정의 할 수 있습니다 . 그러면 JS가 이벤트 에 연결할 수 있습니다 .<input>:-webkit-autofillanimationstart

Klarna UI에 대한 크레딧 . 그들의 훌륭한 구현을 여기에서보십시오 :


이것은 최신 Firefox, Chrome 및 Edge에서 작동합니다.

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

누군가가 솔루션을 찾고있는 경우 (오늘과 마찬가지로) 브라우저 자동 채우기 변경을 청취하기 위해 입력에 변경 리스너를 추가 할 때 프로세스를 단순화하기 위해 내가 작성한 사용자 정의 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!");
});

Google 크롬 자동 완성의 경우 다음과 같이 작동했습니다.

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

나는이 문제에 대해 많이 읽었으며 매우 도움이되는 매우 빠른 해결 방법을 제공하고 싶었습니다.

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

어디에 inputBackgroundNormalState내 템플릿 것은 'RGB (255, 255, 255)'.

따라서 기본적으로 브라우저가 자동 완성을 적용하면 입력에 다른 (성가신) 노란색을 적용하여 입력이 자동으로 채워지는 경향이 있습니다.

편집 : 모든 브라우저에서 작동합니다


불행히도이 크로스 브라우저를 확인하는 유일한 방법은 입력을 폴링하는 것입니다. 반응 형으로 만들려면 이벤트도 듣습니다. Chrome에서 해킹이 필요한 자바 스크립트에서 자동 채우기 값을 숨기기 시작했습니다.

  • 매 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);
    });
    

github 에서이 문제를 해결하기위한 새로운 polyfill 구성 요소가 있습니다. autofill-event를 살펴보십시오 . 설치를 끝내고 설치하면 자동 채우기가 예상대로 작동합니다.

bower install autofill-event

내 해결책 :

change정상적으로 이벤트를 청취 하고 DOM 컨텐츠로드에서 다음을 수행하십시오.

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

이렇게하면 사용자가 편집 할 수 있기 전에 비어 있지 않은 모든 필드에 대한 변경 이벤트가 시작됩니다.


또한 레이블이 자동 채우기를 감지하지 못하고 텍스트를 채울 때 레이블을 움직이는 애니메이션이 겹치는 동일한 문제에 직면 하여이 솔루션이 저에게 효과적이었습니다.

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

나는 비슷한 것을 찾고 있었다. 크롬 전용 ... 필자의 경우 래퍼 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>

나는 이것이 오래된 스레드라는 것을 알고 있지만 많은 사람들이 이것에 대한 해결책을 찾는다고 상상할 수 있습니다.

이를 위해 다음과 같이 입력에 값이 있는지 확인할 수 있습니다.

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

제출 버튼을 활성화하기 위해로드 할 때 로그인 양식에서 값을 확인하기 위해 이것을 직접 사용합니다. 코드는 jQuery 용으로 만들어졌지만 필요한 경우 쉽게 변경할 수 있습니다.


이 질문에 대한 완벽한 해결책이 있습니다.이 코드 스 니펫을 사용해보십시오.
데모는 여기

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>


크롬에서는 자동 완성 요소에 대한 특수 CSS 규칙을 설정 한 다음 요소에 해당 규칙이 적용되어 있는지 자바 스크립트로 확인하여 자동 완성 필드를 감지 할 수 있습니다.

예:

CSS

input:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 30px white inset;
}

자바 스크립트

  let css = $("#selector").css("box-shadow")
  if (css.match(/inset/))
    console.log("autofilled:", $("#selector"))

다음은 Klarna UI 팀에서 가져온 CSS 솔루션입니다. 여기에 자신의 좋은 구현을 참조하십시오 자원을

나를 위해 잘 작동합니다.

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

나는이 문제를 같은 문제에 사용했다.

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

이것은 웹킷 렌더링 엔진이있는 브라우저를위한 솔루션입니다 . 양식이 자동 완성되면 입력은 의사 클래스 : -webkit-autofill- (fe 입력 : -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>

그리고 자바 스크립트 :

$(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);

});

페이지를로드 할 때 문제는 암호 값, 심지어 길이를 얻는 것입니다. 브라우저의 보안 때문입니다. 또한 timeout 은 브라우저가 시간 순서 후에 양식을 채 웁니다.

이 코드는 채워진 입력에 auto_filled 클래스를 추가 합니다. 또한 입력 유형 암호 값 또는 길이를 확인하려고 시도했지만 페이지에서 이벤트가 발생한 직후에 작동했습니다. 그래서 나는 어떤 사건을 일으키려고했지만 성공하지 못했습니다. 지금은 이것이 나의 해결책입니다. 즐겨!


암호 필드가 자동으로 채워 졌는지 확인하기 위해 사용자 이름에 blur 이벤트를 사용했습니다.

 $('#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';

이 입력을 양식에 추가하고 양식 제출시 해당 값을 확인하십시오.


않는다 (적어도 크롬) 폴링에 의존하지 않는 이에 대한 해결책이 될 것으로 보인다. 그것은 거의 hackish이지만 글로벌 폴링보다 조금 더 낫다고 생각합니다.

다음 시나리오를 고려하십시오.

  1. 사용자가 field1 작성을 시작합니다

  2. 사용자가 field2 및 field3을 자동 완성하는 자동 완성 제안을 선택합니다.

솔루션 : 다음 jQuery 스 니펫 $ ( ':-webkit-autofill')을 통해 자동 입력 필드가 있는지 확인하는 모든 필드에 onblur를 등록하십시오.

사용자가 field1을 흐리게 할 때까지 지연되기 때문에 즉각적이지 않지만, 글로벌 폴링에 의존하지 않으므로 IMO가 더 나은 솔루션입니다.

즉, Enter 키를 누르면 양식을 제출할 수 있으므로 onkeypress에 해당하는 핸들러가 필요할 수도 있습니다.

또는 전역 폴링을 사용하여 $ ( ':-webkit-autofill')을 확인할 수 있습니다


내 개인적인 경험에서, 아래 코드는 firefox IE 및 safari와 잘 작동하지만 크롬에서 자동 완성을 선택하는 데별로 효과가 없습니다.

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

나는 크롬으로 성공했다.

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

조사 후 문제는 웹킷 브라우저가 자동 완성시 변경 이벤트를 시작하지 않는다는 것입니다. 내 솔루션은 웹 키트가 추가하고 자동으로 변경 이벤트를 트리거하는 자동 완성 클래스를 얻는 것입니다.

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

다음은 크롬 문제에 대한 링크입니다. https://bugs.chromium.org/p/chromium/issues/detail?id=636425


CSS를 사용해보십시오

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

참고 URL : https://stackoverflow.com/questions/11708092/detecting-browser-autofill

반응형