Phát hiện tự động điền trình duyệt


165

Làm thế nào để bạn biết nếu một trình duyệt đã tự động điền vào một hộp văn bản? Đặc biệt với hộp tên người dùng và mật khẩu tự động điền xung quanh tải trang.

Câu hỏi đầu tiên của tôi là khi nào điều này xảy ra trong trình tự tải trang? Là trước hay sau tài liệu. Đã có?

Thứ hai, làm thế nào tôi có thể sử dụng logic để tìm hiểu nếu điều này xảy ra? Nó không phải là tôi muốn ngăn chặn điều này xảy ra, chỉ cần tham gia vào sự kiện. Tốt nhất là một cái gì đó như thế này:

if (autoFilled == true) {

} else {

}

Nếu có thể tôi rất thích thấy một jsfiddle hiển thị câu trả lời của bạn.

Bản sao có thể

Sự kiện DOM cho tự động điền mật khẩu trình duyệt?

Trình duyệt tự động kích hoạt và sự kiện kích hoạt Javascript

--Bo những câu hỏi này không thực sự giải thích những sự kiện nào được kích hoạt, chúng chỉ liên tục kiểm tra lại hộp văn bản (không tốt cho hiệu suất!).


1
Việc kiểm tra mất vài micro giây trong khi khoảng thời gian sẽ thực hiện kiểm tra cứ sau 100 mili giây hoặc lâu hơn ... điều đó sẽ ảnh hưởng đến hiệu suất như thế nào? Nếu có một sự kiện được trình duyệt kích hoạt, tôi chắc chắn họ sẽ sử dụng nó.
Esailija

Tôi hiểu ý của bạn, nhưng nó phụ thuộc vào phần đầu tiên trong câu hỏi của tôi liệu JavaScript có nhận biết được một thay đổi vừa xảy ra hay không (ví dụ trước tài liệu. Đã sẵn sàng)
Không xác định

1
Giải pháp TỐT NHẤT cho Chrome / WebKit là sử dụng bộ chọn DOM: document.querySelector ALL ('input: -webkit-autofill'); sau một thời gian trì hoãn ngắn setTimeout (... mã ở đây ... 250);
ChrisN

về cơ bản tôi muốn tự động đăng nhập người dùng nếu nó được tự động điền, thật khó chịu khi đăng nhập lại khi nó tự động đăng xuất.
Muhammad Umer

@ChrisN Nhận xét của bạn là những gì thực sự mang lại cho tôi một giải pháp (đơn giản). Tuy nhiên, tôi không xem đó là một câu trả lời! Đăng nó dưới dạng một và ping tôi, để tôi có thể nâng cao nó trong lời cảm ơn.
Ethan Kaminski

Câu trả lời:


123

Vấn đề là tự động điền được xử lý khác nhau bởi các trình duyệt khác nhau. Một số gửi sự kiện thay đổi, một số thì không. Vì vậy, gần như không thể nối vào một sự kiện được kích hoạt khi trình duyệt tự động hoàn thành một trường đầu vào.

  • Thay đổi kích hoạt sự kiện cho các trình duyệt khác nhau:

    • Đối với trường tên người dùng / mật khẩu:

      1. Firefox 4, IE 7 và IE 8 không gửi sự kiện thay đổi.
      2. Safari 5 và Chrome 9 thực hiện sự kiện thay đổi.
    • Đối với các trường mẫu khác:

      1. IE 7 và IE 8 không gửi sự kiện thay đổi.
      2. Firefox 4 không gửi sự kiện thay đổi thay đổi khi người dùng chọn một giá trị từ danh sách các đề xuất và tab ngoài trường.
      3. Chrome 9 không gửi sự kiện thay đổi.
      4. Safari 5 không gửi sự kiện thay đổi.

Các tùy chọn tốt nhất của bạn là vô hiệu hóa tự động hoàn thành cho một biểu mẫu bằng cách sử dụng autocomplete="off"biểu mẫu của bạn hoặc thăm dò ý kiến ​​trong khoảng thời gian thông thường để xem nếu nó được điền.

Đối với câu hỏi của bạn về việc nó được điền vào hoặc trước tài liệu. Một lần nữa, nó thay đổi tùy theo trình duyệt và thậm chí phiên bản sang phiên bản. Chỉ dành cho trường tên người dùng / mật khẩu khi bạn chọn trường mật khẩu tên người dùng được điền. Vì vậy, hoàn toàn bạn sẽ có một mã rất lộn xộn nếu bạn cố gắng đính kèm vào bất kỳ sự kiện.

Bạn có thể đọc tốt về điều này TẠI ĐÂY


26
Xin lưu ý rằng có một sự khác biệt giữa tự động hoàn thành và tự động điền. OP đặc biệt đề cập đến các trình duyệt điền chi tiết đăng nhập đã lưu khi tải trang.
Robbert

2
Một hack thông thường là một mousenter trên một số phần quan trọng của trang. Sự kiện này được kích hoạt khi đầu chuột của người dùng cho nút hoặc một số thứ như vậy.
Bryce

1
@Bryce Cá nhân tôi sẽ đi với một sự kiện 'mờ' do tự động điền là một cái gì đó xảy ra sau khi bạn sẽ vào khu vực đầu vào. Rõ ràng nó không lý tưởng nhưng như một dự phòng cho các trình duyệt được liệt kê ở trên có thể rất hữu ích
JakeJ

Đừng quên inputsự kiện này. Đó là những gì Chrome kích hoạt khi tự động hoàn tất (và có lẽ cũng tự động điền, nếu Chrome có điều đó; tôi luôn tắt công cụ này).
TJ Crowder

Xem câu trả lời một dòng của tôi nếu bạn chỉ muốn biết liệu giá trị trong hộp văn bản có được điền đầy đủ bởi google chrome autocomplete hay không.
ThdK

70

Giải pháp cho trình duyệt WebKit

Từ các tài liệu MDN cho lớp giả CSS : -webkit-autofill CSS:

Lớp giả CSS: -webkit-autofill khớp với khi một phần tử có giá trị được trình duyệt tự động điền

Chúng ta có thể định nghĩa một quy tắc css chuyển tiếp void trên <input>phần tử mong muốn khi nó được :-webkit-autofilled. Sau đó, JS sẽ có thể nối vào animationstartsự kiện này.

Tín dụng cho nhóm UI Klarna . Xem triển khai tốt đẹp của họ ở đây:


1
đây là giải pháp tốt nhất Kudos để Lev ở đây cho điều này. Cảm ơn đã chia sẻ giải pháp của Klarna UI ... không có gì khác làm việc cho tôi cho đến khi tôi tìm thấy giải pháp này. Cuộc sống tiết kiệm!
Braden Rockwell Napier

1
Cũng như các quy tắc CSS, các khung hình chính ở đây github.com/klarna/ui/blob/v4.10.0/Field/styles.scss#L181-L189 cũng cần thiết
user1069816

Điều này làm việc hoàn hảo cho tôi! Cần phải chơi xung quanh với nó một chút để tìm ra cách tiếp cận chính xác. Cảm ơn bạn Klarna đội
pritesh

18

Điều này hoạt động với tôi trong Firefox, Chrome và Edge mới nhất:

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

6
'input'! Đây là giải pháp dễ nhất đối với tôi, nhưng tôi chỉ thử nghiệm tự động hoàn tất, không phải tự động điền.
GreenRaccoon23

Blur không hoạt động với tôi với một số tiện ích bổ sung hoàn thành tự động
tìm đường

Đầu vào sẽ kích hoạt trên mọi phím bấm. Nếu bạn thực hiện một cuộc gọi máy chủ, nó có thể kích hoạt thường xuyên.
RiZKiT

Giải pháp tuyệt vời! Sự kiện kết hợp này giải quyết vấn đề với điền bởi người dùng và tự động điền bằng trình duyệt.
Petr Hladík

17

Đối với google chrome autocomplete, điều này làm việc cho tôi:

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

Nó làm việc cho tôi là tốt. Tôi đã thử hàng trăm giải pháp và không ai làm việc. Cảm ơn bạn rất nhiều, tiết kiệm ngày của tôi và tất cả những lần tôi tìm kiếm một giải pháp.
perozzo

4
Cách tiếp cận này gây ra lỗi: "Lỗi cú pháp, biểu hiện không được nhận dạng: giả không được hỗ trợ: -webkit-autofill" trên các trình duyệt khác (tôi đã thử trên Firefox)
anvita surapaneni

1
Không hoạt động trên chrome cũng như năm 2020, cũng ném lỗi biểu hiện không được nhận dạng: giả không được hỗ trợ: -webkit-autofill
Leo

15

Chỉ trong trường hợp ai đó đang tìm kiếm giải pháp (giống như tôi ngày nay), để lắng nghe thay đổi tự động điền trình duyệt, đây là phương pháp jquery tùy chỉnh mà tôi đã tạo, chỉ để đơn giản hóa bộ xử lý khi thêm trình nghe thay đổi vào đầu vào:

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

Bạn có thể gọi nó như thế này:

$("#myInput").allchange(function () {
    alert("change!");
});

1
Vì một số lý do đối với tôi, mã này không hoạt động trên chuyển hướng trang (khi tôi đăng xuất ứng dụng và được chuyển hướng đến trang đăng nhập nơi xảy ra tự động điền). Mặc dù nó không hoạt động trên làm mới trang.
VishwaKumar

1
Trông giống như bộ xả pin di động: /
Stefan Fisk

@StefanFisk - Không thực sự như vậy. Một bộ đếm thời gian lặp lại đơn giản được đặt ở cấp độ JS của trang trình duyệt là không đủ để tác động đến pin của bạn, vì có quá nhiều thứ đang diễn ra trong hầu hết các trang web .... Bạn thực sự nghĩ rằng google.com không đặt bộ định thời định kỳ? Thật là một lỗi quản lý năng lượng nếu tôi có thể lập trình đơn giản với JS một trang web làm cạn
kiệt

15

Tôi đã đọc rất nhiều về vấn đề này và muốn cung cấp một cách giải quyết rất nhanh đã giúp tôi.

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

trong đó inputBackgroundNormalStatemẫu của tôi là 'rgb (255, 255, 255)'.

Vì vậy, về cơ bản khi các trình duyệt áp dụng tự động hoàn tất, họ có xu hướng chỉ ra rằng đầu vào được tự động điền bằng cách áp dụng một màu vàng (gây khó chịu) khác trên đầu vào.

Chỉnh sửa: điều này hoạt động cho mọi trình duyệt


Suy nghĩ tuyệt vời!
moto

7

Thật không may, cách đáng tin cậy duy nhất tôi đã tìm thấy để kiểm tra trình duyệt chéo này là thăm dò ý kiến ​​đầu vào. Để làm cho nó đáp ứng cũng lắng nghe các sự kiện. Chrome đã bắt đầu ẩn các giá trị tự động điền từ javascript cần hack.

  • Thăm dò mỗi nửa đến một phần ba giây (Không cần phải ngay lập tức trong hầu hết các trường hợp)
  • Kích hoạt sự kiện thay đổi bằng JQuery, sau đó thực hiện logic của bạn trong một hàm lắng nghe sự kiện thay đổi.
  • Thêm một sửa chữa cho các giá trị mật khẩu tự động ẩn của 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

Có một thành phần polyfill mới để giải quyết vấn đề này trên github. Có một cái nhìn vào sự kiện tự động điền . Chỉ cần bower cài đặt nó và voilà, tự động điền hoạt động như mong đợi.

bower install autofill-event

Điều này hoạt động rất tốt với jQuery Custom Forms. Tôi vừa bỏ nó vào và danh sách lựa chọn tùy chỉnh của tôi hoạt động rất tốt với tính năng tự động điền.
Chris Bloom

6

Giải pháp của tôi:

Nghe changecác sự kiện như bình thường và trên tải nội dung DOM, hãy làm điều này:

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

Điều này sẽ kích hoạt các sự kiện thay đổi cho tất cả các trường không trống trước khi người dùng có cơ hội chỉnh sửa chúng.


Hoàn hảo. Giải pháp đầu tiên tôi thấy làm việc với Chrome!
Thoát khỏi

3
Đó thực sự là @RidIculous một số giải pháp có thể đơn giản như thế nào.
Camilo Martin

3
Nhưng elem.val () trả về chuỗi trống cho các trường mật khẩu được điền tự động trong chrome :(
Hemant_Negi 16/07/2015

@Hemant_Negi Dù sao Chrome cũng không gửi sự kiện thay đổi? Sửa tôi nếu tôi sai. Tôi đang sử dụng LastPass và quá lười để vô hiệu hóa nó để xem nó cũng hoạt động mà không có.
Camilo Martin

1
Có sự kiện thay đổi công văn chrome, nhưng khi tôi cố gắng lấy giá trị thì nó trả về sản phẩm nào.
Hemant_Negi

4

Tôi cũng gặp phải vấn đề tương tự khi nhãn không phát hiện tự động điền và hình động để di chuyển nhãn khi điền văn bản bị chồng chéo và giải pháp này hiệu quả với tôi.

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

Điều này rất hữu ích.
rustyshackleford

Chính xác những gì tôi cần :)
Dabrule

4

Tôi đang tìm kiếm một điều tương tự. Chỉ Chrome ... Trong trường hợp của tôi, div trình bao bọc cần biết liệu trường nhập liệu có được tự động điền hay không. Vì vậy, tôi có thể cung cấp cho nó thêm css giống như Chrome thực hiện trên trường đầu vào khi nó tự động điền. Bằng cách xem xét tất cả các câu trả lời ở trên, giải pháp kết hợp của tôi là như sau:

/* 
 * 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 để làm việc này sẽ là

<div class="input-wrapper">
    <input type="text" name="firstname">
</div>

3

Tôi biết đây là một chủ đề cũ nhưng tôi có thể tưởng tượng nhiều người đến để tìm một giải pháp cho vấn đề này ở đây.

Để thực hiện việc này, bạn có thể kiểm tra xem (các) đầu vào có (các) giá trị với:

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

Tôi sử dụng chính nó để kiểm tra các giá trị trong biểu mẫu đăng nhập của mình khi nó được tải để kích hoạt nút gửi. Mã được tạo cho jQuery nhưng rất dễ thay đổi nếu cần.


1
Mã này hoạt động rất tốt đối với tôi nếu bạn cập nhật dòng thứ ba thành($("#inputID:-webkit-autofill").val().length > 0) {
Hector

3

Đây là giải pháp cho các trình duyệt với công cụ kết xuất webkit . Khi biểu mẫu được tự động điền, các đầu vào sẽ có lớp giả : -webkit-autofill- (đầu vào: -webkit-autofill {...}). Vì vậy, đây là định danh những gì bạn phải kiểm tra thông qua JavaScript.

Giải pháp với một số hình thức kiểm tra:

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

Và 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);

});

Vấn đề khi tải trang là nhận được giá trị mật khẩu, thậm chí chiều dài. Điều này là do bảo mật của trình duyệt. Ngoài ra, thời gian chờ là do trình duyệt sẽ điền vào biểu mẫu sau một khoảng thời gian.

Mã này sẽ thêm lớp auto_filling vào các đầu vào được điền. Ngoài ra, tôi đã cố kiểm tra giá trị mật khẩu loại đầu vào hoặc độ dài, nhưng nó đã hoạt động ngay sau khi một số sự kiện trên trang xảy ra. Vì vậy, tôi đã thử kích hoạt một số sự kiện, nhưng không thành công. Bây giờ đây là giải pháp của tôi. Thưởng thức!


Đây là câu trả lời cập nhật.
Ben Racicot

Tôi đã thử giải pháp này và làm việc rất tốt cho tôi. Cảm ơn rât nhiều.
Marcus Crisostomo

2

Tôi có giải pháp hoàn hảo cho câu hỏi này hãy thử đoạn mã này.
Demo ở đây

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

Trên chrome, bạn có thể phát hiện các trường tự động điền bằng cách cài đặt quy tắc css đặc biệt cho các phần tử tự động điền, sau đó kiểm tra bằng javascript nếu phần tử đó được áp dụng quy tắc đó.

Thí dụ:

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

Đây là giải pháp CSS được lấy từ nhóm UI Klarna. Xem thực hiện đẹp của họ vào đây tài nguyên

Hoạt động tốt cho tôi.

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

1

Tôi đã sử dụng giải pháp này cho cùng một vấn đề.

Mã HTML nên thay đổi thành:

<input type="text" name="username" />
<input type="text" name="password" id="txt_password" />

và mã jQuery phải ở trong document.ready:

$('#txt_password').focus(function(){
    $(this).attr('type','password');
});

0

Tôi đã sử dụng sự kiện làm mờ trên tên người dùng để kiểm tra xem trường pwd đã được tự động điền chưa.

 $('#userNameTextBox').blur(function () {
        if ($('#userNameTextBox').val() == "") {
            $('#userNameTextBox').val("User Name");
        }
        if ($('#passwordTextBox').val() != "") {
            $('#passwordTextBoxClear').hide(); // textbox with "Password" text in it
            $('#passwordTextBox').show();
        }
    });

Điều này hoạt động với IE và nên hoạt động cho tất cả các trình duyệt khác (Tôi chỉ kiểm tra IE)


@ChrisN Tôi đã thử nghiệm giải pháp của mình với IE, các trình duyệt xử lý các sự kiện javascsript khác nhau. Giải pháp của tôi rất đơn giản và dễ đọc và dành cho một trong những trình duyệt khó viết mã hơn.
Bridget Arrington

1
Tôi kết thúc với cùng một giải pháp: blursự kiện. Tôi áp dụng các chức năng tương tự cho changeblursự kiện và nó làm việc tuyệt vời. Một giải pháp đơn giản mà không cần thêm thư viện.
Paulo Kiểm tra

0

Tôi đã có cùng một vấn đề và tôi đã viết giải pháp này.

Nó bắt đầu bỏ phiếu trên mọi trường đầu vào khi trang đang tải (Tôi đã đặt 10 giây nhưng bạn có thể điều chỉnh giá trị này).
Sau 10 giây, nó dừng bỏ phiếu trên mọi trường đầu vào và nó chỉ bắt đầu bỏ phiếu trên đầu vào tập trung (nếu có). Nó dừng lại khi bạn làm mờ đầu vào và bắt đầu lại nếu bạn tập trung vào một.

Bằng cách này, bạn chỉ thăm dò ý kiến ​​khi thực sự cần thiết và chỉ trên một đầu vào hợp lệ.

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

Nó không hoạt động khá tốt khi bạn có nhiều giá trị được chèn tự động, nhưng nó có thể được điều chỉnh để tìm mọi đầu vào trên biểu mẫu hiện tại.

Cái gì đó như:

// 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

Nếu bạn chỉ muốn phát hiện xem tự động điền đã được sử dụng hay chưa, thay vì phát hiện chính xác thời điểm và trường tự động điền đã được sử dụng, bạn có thể chỉ cần thêm một yếu tố ẩn sẽ được tự động điền và sau đó kiểm tra xem chứa bất kỳ giá trị nào. Tôi hiểu rằng đây có thể không phải là điều mà nhiều người quan tâm. Đặt trường đầu vào với tab Index âm và có tọa độ tuyệt đối ngoài màn hình. Điều quan trọng là đầu vào là một phần của cùng một hình thức với phần còn lại của đầu vào. Bạn phải sử dụng tên sẽ được chọn bằng Tự động điền (ví dụ: "tên hiệu").

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

Nối đầu vào này vào biểu mẫu và kiểm tra giá trị của nó trên biểu mẫu gửi.


0

không xuất hiện như một giải pháp này mà không dựa vào điểm bỏ phiếu (ít nhất là cho Chrome). Nó gần như là hackish, nhưng tôi nghĩ là tốt hơn so với bỏ phiếu toàn cầu.

Hãy xem xét kịch bản sau đây:

  1. Người dùng bắt đầu điền vào trường1

  2. Người dùng chọn đề xuất tự động hoàn thành tự động điền trường2 và trường3

Giải pháp: Đăng ký một onblur trên tất cả các trường kiểm tra sự hiện diện của các trường được điền tự động thông qua đoạn mã jQuery sau (': - webkit-autofill')

Điều này sẽ không ngay lập tức vì nó sẽ bị trì hoãn cho đến khi người dùng làm mờ trường1 nhưng nó không phụ thuộc vào việc bỏ phiếu toàn cầu vì vậy IMO, đó là một giải pháp tốt hơn.

Điều đó nói rằng, vì nhấn phím enter có thể gửi biểu mẫu, bạn cũng có thể cần một trình xử lý tương ứng cho onkeypress.

Thay phiên, bạn có thể sử dụng bỏ phiếu toàn cầu để kiểm tra $ (': - webkit-autofill')


0

Từ kinh nghiệm cá nhân của tôi, đoạn mã dưới đây hoạt động tốt với firefox IE và safari, nhưng không hoạt động tốt trong việc chọn tự động hoàn thành trong chrome.

function check(){
clearTimeout(timeObj);
 timeObj = setTimeout(function(){
   if($('#email').val()){
    //do something
   }
 },1500);
}

$('#email').bind('focus change blur',function(){
 check();
});

Mã bên dưới hoạt động tốt hơn, bởi vì nó sẽ kích hoạt mỗi khi người dùng nhấp vào trường đầu vào và từ đó bạn có thể kiểm tra trường đầu vào có trống hay không.

$('#email').bind('click', function(){
 check();
});

0

Tôi đã thành công trên chrome với:

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

Không chắc chắn khi chính xác Chrome tự động chạy, nhưng trong $ ('đầu vào, chọn'). On ('Focusin', function (evt) {...}); Tôi nhận được giá trị tự động điền cho tất cả các trường.
mirek

Phiên bản mới có thể?
Antoine O

0

Giải pháp của tôi là:

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

Một lời giải thích cho giải pháp của bạn sẽ có ích
tấn

Tôi nghĩ rằng nó rõ ràng. Vì vậy, về cơ bản ý tưởng là để kiểm tra giá trị của trường đầu vào vài lần. Trong triển khai hiện tại, nó là 10 lần với độ trễ 100 ms. Vì vậy, trong khi trình duyệt 10 * 1000 = 1 giây thứ hai điền vào giá trị tự động điền thì cuộc gọi lại được chuyển sang tự động điền sẽ được gọi. Trong ví dụ hiện tại, nó chỉ thêm một lớp. Nếu bạn có thêm câu hỏi xin đừng ngần ngại và chỉ cần hỏi :).
Romick

0

Sau khi nghiên cứu vấn đề là các trình duyệt webkit không kích hoạt sự kiện thay đổi trên tự động hoàn tất. Giải pháp của tôi là lấy lớp tự động điền mà webkit thêm và kích hoạt sự kiện thay đổi một mình.

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

Đây là một liên kết cho vấn đề trong crom. https://bugs.chromium.org/p/chromium/issues/detail?id=636425


0

Để phát hiện email chẳng hạn, tôi đã thử "thay đổi" và một người quan sát đột biến, đều không hoạt động. setInterval hoạt động tốt với tính năng tự động điền LinkedIn (không tiết lộ tất cả mã của tôi, nhưng bạn hiểu ý) và nó hoạt động tốt với phần phụ trợ nếu bạn thêm các điều kiện bổ sung vào đây để làm chậm AJAX. Và nếu không có thay đổi trong trường biểu mẫu, như họ không gõ để chỉnh sửa email của họ, LastEmail sẽ ngăn chặn các lệnh AJAX vô nghĩa.

// 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

Tôi đã có một thời gian khó khăn để phát hiện tự động điền vào Firefox. Đây là giải pháp duy nhất hiệu quả với tôi:

Bản giới thiệu

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

  }); 

Đối với Chrome tôi sử dụng: if ($(this).css('animation-name') == 'onAutoFillStart')

Đối với Firefox: if ($(this).val() != '')


-2

thử trong CSS

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.