检测浏览器自动填充


165

您如何判断浏览器是否自动填充了文本框?尤其是用户名和密码框会自动填充页面加载。

我的第一个问题是页面加载序列何时发生?是在document.ready之前还是之后?

其次,我该如何使用逻辑找出这种情况是否发生?它不是我想阻止这种情况发生,只是挂接到事件中。最好是这样的:

if (autoFilled == true) {

} else {

}

如果可能的话,我希望看到一个jsfiddle显示您的答案。

可能重复

浏览器密码自动填充的DOM事件?

浏览器自动填充和JavaScript触发的事件

-这两个问题并不能真正解释触发了什么事件,它们只是不断地重新检查文本框(不利于性能!)。


1
检查需要几微秒,而间隔将每隔100毫秒左右触发一次检查...这将完全影响性能吗?如果存在浏览器触发的事件,我确定他们会使用它。
Esailija

我明白您的意思了,但这取决于我问题的第一部分,即JavaScript是否甚至意识到刚刚发生了更改(例如,在document.ready之前)
未定义2012年

1
Chrome / WebKit的最佳解决方案是使用DOM选择器:document.querySelectorAll('input:-webkit-autofill'); 短暂延迟后setTimeout(...这里的代码... 250);
ChrisN 2015年

基本上,我想自动登录用户,如果它是自动填充的,那么当它自动注销时,恼人的ot重新登录。
穆罕默德·乌默

@ChrisN您的评论实际上是为我提供了一个(简单的)解决方案。不过,我不认为这是答案!将其发布为一个,然后对我执行ping操作,这样我就可以对其表示感谢。
伊桑·卡明斯基

Answers:


123

问题是自动填充由不同的浏览器处理。有些派遣变更事件,有些则没有。因此,几乎不可能挂接在浏览器自动完成输入字段时触发的事件。

  • 更改不同浏览器的事件触发器:

    • 对于用户名/密码字段:

      1. Firefox 4,IE 7和IE 8不会调度change事件。
      2. Safari 5和Chrome 9确实会调度更改事件。
    • 对于其他表单字段:

      1. IE 7和IE 8不会调度change事件。
      2. 当用户从建议列表中选择一个值并跳出字段时,Firefox 4确实调度了更改更改事件。
      3. Chrome 9不会调度更改事件。
      4. Safari 5确实调度了change事件。

您最好的选择是使用以下方式禁用表单的自动完成功能: autocomplete="off"的表单的或者定期轮询以查看其是否已填写。

关于您是否在文档上填充文档或文档之前的问题,请再次阅读,不同的浏览器甚至不同的版本都有不同。对于用户名/密码字段,仅当您选择用户名时才填写密码字段。因此,如果您尝试附加到任何事件,那么总共会有一个非常混乱的代码。

您可以在这里阅读


26
请注意,自动完成和自动填充之间是有区别的。OP特别是指浏览器在页面加载时填写保存的登录详细信息。
罗伯特

2
常见的骇客行为是该页面某些重要部分的诱饵。当用户的鼠标头按下按钮或类似按钮时,将触发该事件。
布莱斯

1
@Bryce就我个人而言,我会遇到“模糊”事件,因为自动填充是在您进入输入区域之后发生的事情。显然这并不理想,但是作为上述浏览器的后备设备,它可能会非常有帮助
JakeJ 2014年

不要忘记input事件。这就是Chrome在自动完成时触发的功能(如果Chrome具有自动填充功能,则可能会自动填充;我总是将其关闭)。
TJ Crowder 2014年

如果您只想知道文本框中的值是否由Google chrome自动填充功能填充,请查看我的第一行答案。
ThdK

70

WebKit浏览器解决方案

从MDN文档::-webkit-autofill CSS伪类:

当一个元素的值被浏览器自动填充时,:-webkit-autofill CSS伪类匹配

ed 之后,我们可以在所需元素上定义一个void transition css规则。然后,JS将可以挂接到<input>:-webkit-autofillanimationstart事件上。

感谢Klarna UI团队。在此处查看其不错的实现:


1
到目前为止,这是最好的解决方案!为此,Lev非常荣幸。感谢您分享Klarna UI的解决方案...在我找到这个之前,没有其他工作对我有用。救命!
Braden Rockwell Napier

1
除了CSS规则外,这里还需要关键帧github.com/klarna/ui/blob/v4.10.0/Field/styles.scss#L181-L189
user1069816

这对我来说完美无缺!需要稍微弄清楚它的确切方法。谢谢克拉纳团队
pritesh '18

18

这在最新的Firefox,Chrome和Edge中对我有效:

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

6
'input'!这对我来说是最简单的解决方案,但是我只测试了自动填充功能,而不是自动填充功能。
GreenRaccoon23年

模糊不适合我使用某些自动完成加载项
探路者

输入将在每次按键时触发。如果执行服务器调用,则可能会触发。
RiZKiT

很好的解决方案!此事件组合解决了用户填充和浏览器自动填充的问题。
PetrHladík18年

17

对于谷歌浏览器自动完成功能,这对我有用:

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

它也对我有用。我尝试了数百种解决方案,但没人能解决。非常感谢您,节省我的时间,也一直在寻找解决方案。
perozzo

4
此方法引发错误:在其他浏览器上的语法错误,无法识别的表达式:不支持的伪:-webkit-
autofill

1
在chrome上以及2020年都无法正常运行,还会引发错误无法识别的表达式:不支持的伪代码:-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-并非如此。在浏览器页面的JS级别上设置一个简单的重复计时器不足以影响您的电池,因为大多数网页中发生的事情太多....您真的认为google.com没有设置重复计时器吗?如果我可以简单地用JS编程消耗用户电量的网页,那将是一个电源管理缺陷
。.– LcSalazar

15

我阅读了很多有关此问题的内容,并希望提供一个非常快速的解决方法来帮助我。

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

在那里inputBackgroundNormalState我的模板是'RGB(255,255,255)'。

因此,基本上,当浏览器应用自动完成功能时,它们倾向于通过在输入上应用不同的(讨厌的)黄色来指示输入是自动填充的。

编辑:这适用于所有浏览器


好主意!
moto

7

不幸的是,我发现检查此跨浏览器的唯一可靠方法是轮询输入。要使其响应,还可以监听事件。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);
    });

6

在github上有一个新的polyfill组件可以解决这个问题。看一下autofill-event。只需安装凉亭并安装,自动填充即可正常工作。

bower install autofill-event

这与jQuery Custom Forms一起使用效果很好。我刚将其放入,我的自定义选择列表与自动填充效果很好。
克里斯·布鲁姆

6

我的解决方案:

change像往常一样监听事件,并在DOM内容负载下执行以下操作:

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

这将在用户有机会编辑所有非空字段之前触发更改事件。


完善。我发现使用Chrome的第一个解决方案!
Rid Iculous

3
确实,@ RidIculous一些解决方案可以多么简单。
卡米洛·马丁

3
但是elem.val()对于chrome自动填充的密码字段返回空字符串:(
Hemant_Negi

@Hemant_Negi Chrome是否仍未调度更改事件?如我错了请纠正我。我正在使用LastPass,并且懒得禁用它以查看它是否也可以工作。
卡米洛·马丁

1
是chrome调度更改事件,但是,当我尝试检索该值时,它返回空值。
Hemant_Negi

4

我还遇到了相同的问题,即标签未检测到自动填充,并且在填充文本时移动标签的动画存在重叠,因此该解决方案对我有用。

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

这是有帮助的。
rustyshackleford

正是我所需要的:)
Dabrule

4

我在寻找类似的东西。仅适用于Chrome ...对于我来说,包装器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>

3

我知道这是一个旧线程,但是我可以想象很多人会在这里找到解决方案。

为此,您可以使用以下命令检查输入是否具有值:

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

当加载登录表单以启用提交按钮时,我自己使用它来检查登录表单中的值。该代码是针对jQuery制作的,但如果需要,可以轻松更改。


1
如果您将第三行更新为($("#inputID:-webkit-autofill").val().length > 0) {
Hector

3

这是使用webkit渲染引擎的浏览器的解决方案。自动填写表单后,输入将变为伪类:-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>

和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

我在用户名上使用了模糊事件来检查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
我最终得到了相同的解决方案:blur事件。我对changeblur事件应用了相同的功能,效果很好。一个没有额外库的简单解决方案。
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

那里 确实似乎对这种不依赖于轮询(至少铬)的解决方案。它几乎像黑客一样,但我确实比全球民意测验好一点。

请考虑以下情形:

  1. 用户开始填写字段1

  2. 用户选择自动填充字段2和字段3的自动完成建议

解决方案:在所有字段上注册onblur,以通过以下jQuery代码段$(':-webkit-autofill')检查是否存在自动填充的字段

这不会立即生效,因为它将被延迟到用户模糊field1为止,但是它不依赖于全局轮询,因此IMO是一个更好的解决方案。

就是说,由于按Enter键可以提交表单,因此您可能还需要相应的处理程序来进行onkeypress。

或者,您可以使用全局轮询来检查$(':-webkit-autofill')


0

根据我的个人经验,以下代码与Firefox和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

我在chrome上成功实现了:

    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

可能是新版本?
Antoine 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');
          }
      );
  });

对您的解决方案的说明将有所帮助

我以为是明显的。因此,基本上的想法是检查输入字段的值两次。在当前的实现中,它是10次,延迟为100 ms。因此,在第二个10 * 1000 = 1sec浏览器中填充自动填充值时,将调用传递给自动填充的回调。在当前示例中,它仅添加了一个类。如果您还有其他问题,请随时询问:)。
罗米克


0

例如,要检测电子邮件,我尝试了“ on change”和一个变种观察器,但都没有起作用。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() != '')


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.