检测浏览器自动填充
Posted
技术标签:
【中文标题】检测浏览器自动填充【英文标题】:Detecting Browser Autofill 【发布时间】:2012-07-29 09:20:06 【问题描述】:如何判断浏览器是否自动填充了文本框?尤其是在页面加载时自动填充的用户名和密码框。
我的第一个问题是这在页面加载序列中何时发生?是在 document.ready 之前还是之后?
其次,我如何使用逻辑来确定是否发生了这种情况?不是我想阻止这种情况发生,只是加入事件。最好是这样的:
if (autoFilled == true)
else
如果可能的话,我希望看到一个 jsfiddle 显示你的答案。
可能的重复
DOM event for browser password autofill?
Browser Autofill and javascript triggered events
--这两个问题都没有真正解释触发了什么事件,它们只是不断地重新检查文本框(不利于性能!)。
【问题讨论】:
检查需要几微秒,而间隔将每 100 毫秒左右触发一次检查......这将如何影响性能?如果存在浏览器触发的事件,我相信他们会使用它。 我明白你的意思,但这取决于我的问题的第一部分,JavaScript 是否知道刚刚发生了变化(例如在 document.ready 之前) Chrome / WebKit 的最佳解决方案是使用 DOM 选择器:document.querySelectorAll('input:-webkit-autofill');经过短暂的延迟 setTimeout(... 这里的代码... 250); 基本上我想自动登录用户,如果它是自动填充的,在它自动注销时又重新登录很烦人。 @ChrisN 您的评论实际上给了我一个(简单的)解决方案。不过,我不认为这是一个答案!将它作为一个发布并 ping 我,所以我可以在感谢中投票。 【参考方案1】:问题是不同浏览器对自动填充的处理方式不同。有些发送更改事件,有些则不发送。因此,几乎不可能挂钩在浏览器自动完成输入字段时触发的事件。
改变不同浏览器的事件触发器:
对于用户名/密码字段:
-
Firefox 4、IE 7 和 IE 8 不调度更改事件。
Safari 5 和 Chrome 9 会调度 change 事件。
对于其他表单域:
-
IE 7 和 IE 8 不调度更改事件。
当用户从建议列表中选择一个值并从字段中跳出标签时,Firefox 4 会调度 change change 事件。
Chrome 9 不会调度更改事件。
Safari 5 确实调度了 change 事件。
您最好的选择是在表单中使用 autocomplete="off"
禁用表单的自动完成功能,或者定期轮询以查看其是否已填写。
对于您是否在 document.ready 之前或之前填写的问题,它因浏览器而异,甚至因版本而异。仅当您选择用户名密码字段时,才会填写用户名/密码字段。因此,如果您尝试附加到任何事件,您将拥有一个非常混乱的代码。
你可以好好阅读这个HERE
【讨论】:
请注意自动填充和自动填充之间的区别。 OP 特指浏览器在页面加载时填写保存的登录详细信息。 通常的黑客攻击是在页面的某些重要部分上插入鼠标。当用户的鼠标指向按钮等时触发该事件。 @Bryce 我个人会选择“模糊”事件,因为自动填充是在您进入输入区域后发生的事情。显然它并不理想,但作为上面列出的浏览器的后备,它可能非常有用 不要忘记input
事件。这就是 Chrome 在自动完成时触发的(如果 Chrome 有,也可能是自动填充;我总是关闭这些东西)。
如果您只想知道文本框中的值是否由谷歌浏览器自动完成填写,请查看我的单行答案。【参考方案2】:
WebKit 浏览器解决方案
来自 :-webkit-autofill CSS 伪类的 MDN 文档:
当一个元素的值被浏览器自动填充时,:-webkit-autofill CSS 伪类匹配
我们可以在所需的<input>
元素上定义一个 void transition css 规则,一旦它是:-webkit-autofill
ed。然后 JS 将能够连接到 animationstart
事件。
感谢Klarna UI 团队。在这里查看他们很好的实现:
CSS rules JS hook【讨论】:
这是迄今为止最好的解决方案!在这里向列夫致敬。感谢您分享 Klarna UI 的解决方案......在我找到这个之前,没有其他任何东西对我有用。救生员! 除了CSS规则,这里github.com/klarna/ui/blob/v4.10.0/Field/styles.scss#L181-L189的关键帧也是需要的 这对我来说完美无缺!需要稍微玩弄一下才能找出确切的方法。感谢 Klarna 团队 可能是因为这个答案很久以前了,但是这个解决方案和 Klarna 的代码对我不起作用,因为我不得不将钩子改为“transitionstart”而不是“animationstart” . ***.com/a/41530600 需要在css动画中添加过渡时间-duration: 0.001s - 否则事件不会在chrome中触发【参考方案3】:这适用于我最新的 Firefox、Chrome 和 Edge:
$('#email').on('blur input', function()
....
);
【讨论】:
'input'
!这对我来说是最简单的解决方案,但我只测试了自动完成,而不是自动填充。
模糊不适用于一些自动完成的附加组件
每次按键都会触发输入。如果您进行服务器调用,它可能会经常触发。
很好的解决方案!这种事件组合解决了用户填充和浏览器自动填充的问题。【参考方案4】:
我阅读了很多有关此问题的信息,并希望提供一个对我有帮助的快速解决方法。
let style = window.getComputedStyle(document.getElementById('email'))
if (style && style.backgroundColor !== inputBackgroundNormalState)
this.inputAutofilledByBrowser = true
我的模板的 inputBackgroundNormalState
是 'rgb(255, 255, 255)'。
因此,基本上,当浏览器应用自动完成功能时,它们往往会通过在输入上应用不同的(烦人的)黄色来指示输入是自动填充的。
编辑:这适用于每个浏览器
【讨论】:
好主意! 这在 Mozilla 上不起作用,因为背景颜色是通过过滤器应用的,背景颜色仍然是默认的 rgb(255, 255, 255)【参考方案5】:对于谷歌浏览器自动完成,这对我有用:
if ($("#textbox").is(":-webkit-autofill"))
// the value in the input field of the form was filled in with google chrome autocomplete
【讨论】:
它也对我有用。我尝试了数百种解决方案,但没有一个奏效。非常感谢,节省了我的时间和我寻找解决方案的所有时间。 这种方法会引发错误:“语法错误,无法识别的表达式:不支持的伪:-webkit-autofill”在其他浏览器上(我在 Firefox 上试过) 不适用于 chrome 以及 2020 版,也会抛出错误无法识别的表达式:不支持的伪:-webkit-autofill【参考方案6】:以防万一有人正在寻找解决方案(就像我今天一样),要监听浏览器自动填充更改,这是我构建的自定义 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!");
);
【讨论】:
出于某种原因,此代码无法用于页面重定向(当我注销应用程序并重定向到发生自动填充的登录页面时)。虽然它确实适用于页面刷新。 看起来很像移动电池消耗器:/ @StefanFisk - 并非如此。在浏览器页面的 JS 级别设置一个简单的重复计时器不足以影响您的电池,因为在大多数网页中都发生了很多事情......你真的认为 google.com不设置循环计时器?如果我可以简单地用 JS 编写一个耗尽用户电池的网页,那将是一个多么大的电源管理缺陷......【参考方案7】:我也遇到了同样的问题,标签没有检测到自动填充,并且在填充文本时移动标签的动画重叠,这个解决方案对我有用。
input:-webkit-autofill ~ label
top:-20px;
【讨论】:
这很有帮助。 正是我需要的:) 这个答案很旧,但它仍然很好用。【参考方案8】:不幸的是,我发现检查此跨浏览器的唯一可靠方法是轮询输入。为了使其响应也听事件。 Chrome 已开始从需要 hack 的 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);
);
【讨论】:
我的问题是使用attr('value')
而不是val()
。与val()
不同,attr('value')
不包含自动填充值 (Firefox)!【参考方案9】:
我的解决方案:
像往常一样收听change
事件,并在加载 DOM 内容时执行以下操作:
setTimeout(function()
$('input').each(function()
var elem = $(this);
if (elem.val()) elem.change();
)
, 250);
这将在用户有机会编辑之前触发所有非空字段的更改事件。
【讨论】:
完美。我发现第一个使用 Chrome 的解决方案! 真的@RidIculous 一些解决方案可以多么简单。 但是 elem.val() 为 chrome 中的自动填充密码字段返回空字符串:( @Hemant_Negi Chrome 不会调度 change 事件吗?如我错了请纠正我。我正在使用 LastPass,我懒得禁用它,看看它是否也能正常工作。 是的 chrome 调度更改事件,但是当我尝试检索它返回空的值时。【参考方案10】:在 github 上有一个新的 polyfill 组件来解决这个问题。看看autofill-event。只需要凉亭安装它,瞧,自动填充按预期工作。
bower install autofill-event
【讨论】:
这对 jQuery 自定义表单非常有效。我刚把它放进去,我的自定义选择列表与自动填充配合得很好。【参考方案11】:我正在寻找类似的东西。仅限 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>
【讨论】:
【参考方案12】:这是来自 Klarna UI 团队的 CSS 解决方案。在这里查看他们很好的实现resource
对我来说很好。
input:-webkit-autofill
animation-name: onAutoFillStart;
transition: background-color 50000s ease-in-out 0s;
input:not(:-webkit-autofill)
animation-name: onAutoFillCancel;
【讨论】:
【参考方案13】:我知道这是一个旧线程,但我可以想象很多人会在这里找到解决方案。
为此,您可以检查输入是否具有以下值:
$(function()
setTimeout(function()
if ($("#inputID").val().length > 0)
// YOUR CODE
, 100);
);
我自己使用它来检查我的登录表单中的值,当它加载以启用提交按钮时。 该代码是为 jQuery 编写的,但如果需要可以很容易地更改。
【讨论】:
如果您将第三行更新为($("#inputID:-webkit-autofill").val().length > 0)
,此代码对我来说非常有用【参考方案14】:
在 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"))
【讨论】:
【参考方案15】:这是带有 webkit 渲染引擎的浏览器的解决方案。 当表单被自动填充时,输入将获得伪类 :-webkit-autofill-(例如 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 添加到已填充的输入中。另外,我尝试检查输入类型密码值或长度,但它在页面上发生某些事件后才起作用。所以我尝试触发一些事件,但没有成功。现在这是我的解决方案。 享受!
【讨论】:
这是最新的答案。 我尝试了这个解决方案,对我来说效果很好。非常感谢。【参考方案16】:我有这个问题的完美解决方案试试这个代码 sn-p。Demo is here
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>
【讨论】:
【参考方案17】:在 Chrome 和 Edge (2020) 中检查 :-webkit-autofill
会告诉您输入已被填充。但是,在用户以某种方式与页面交互之前,您的 JavaScript 无法获取输入中的值。
使用$('x').focus()
和$('x').blur()
或在代码中触发鼠标事件都无济于事。
见https://***.com/a/35783761/32429
【讨论】:
在 Firefox 86 中工作,尽管 MDN 和 caniuse 另有建议。【参考方案18】:在 2020 年,这就是我在 chrome 中的工作:
// wait 0.1 sec to execute action after detecting autofill
// check if input username is autofilled by browser
// enable "login" button for click to submit form
$(window).on("load", function()
setTimeout(function()
if ($("#UserName").is("input:-webkit-autofill"))
$("#loginbtn").prop('disabled', false);
, 100);
);
【讨论】:
【参考方案19】:我花了几个小时解决了在首页加载时检测自动填充输入的问题(没有采取任何用户操作)并找到了适用于 Chrome、Opera、Edge 和 FF 的理想解决方案!
在 Chrome、Opera 上,Edge 问题已经很好解决了
通过使用伪类input:-webkit-autofill
搜索元素并执行所需的操作(在我的情况下,我正在更改输入包装类以使用浮动标签模式更改标签位置)。
问题出在 Firefox 上
因为 FF 没有这样的伪类或类似的类(正如许多人建议的“:-moz-autofill”),只需搜索 DOM 即可看到。您也找不到输入的黄色背景。唯一的原因是浏览器通过更改过滤器属性添加了这种黄色:
input:-moz-autofill, input:-moz-autofill-preview filter: grayscale(21%) brightness(88%) contrast(161%) invert(10%) sepia(40%) saturate(206%);
因此,对于 Firefox,您必须首先搜索所有输入并获取其计算样式,然后与浏览器设置中硬编码的此过滤器样式进行比较。我真的不知道他们为什么不使用简单的背景颜色,而是使用那个奇怪的滤镜!?他们让生活变得更艰难;)
这是我的代码在我的网站 (https://my.oodo.pl/en/modules/register/login.php) 上的工作原理:
<script type="text/javascript">
/*
* this is my main function
*/
var checkAutoFill = function()
/*first we detect if we have FF or other browsers*/
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
if (!isFirefox)
$('input:-webkit-autofill').each(function()
/*here i have code that adds "focused" class to my input wrapper and changes
info instatus div. U can do what u want*/
$(this).closest('.field-wrapper').addClass('focused');
document.getElementById("status").innerHTML = "Your browser autofilled form";
);
if (isFirefox)
$('input').each(function()
var bckgrnd = window.getComputedStyle(document.getElementById(this.id), null).getPropertyValue("background-image");
if (bckgrnd === 'linear-gradient(rgba(255, 249, 145, 0.5), rgba(255, 249, 145, 0.5))')
/*if our input has that filter property customized by browserr with yellow background i do as above (change input wrapper class and change status info. U can add your code here)*/
$(this).closest('.field-wrapper').addClass('focused');
document.getElementById("status").innerHTML = "Your Browser autofilled form";
)
/*im runing that function at load time and two times more at 0.5s and 1s delay because not all browsers apply that style imediately (Opera does after ~300ms and so Edge, Chrome is fastest and do it at first function run)*/
checkAutoFill();
setTimeout(function()
checkAutoFill();
, 500);
setTimeout(function()
checkAutoFill();
, 1000);
)
</script>
我在这里手动编辑了上面的代码,以丢弃一些对你不重要的垃圾。如果它不适合你,那么粘贴到你的 IDE 并仔细检查语法;)当然添加一些调试警报或控制台日志并自定义。
【讨论】:
在新版本的 FF 中,他们改变了自动填充输入的样式。现在他们使用 linear-gradient(rgba(255, 249, 145, 0.5), rgba(255, 249, 145, 0.5)) 作为背景图像的属性。我更改了代码。【参考方案20】:我用这个解决方案解决了同样的问题。
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');
);
【讨论】:
【参考方案21】:对于正在寻找 2020 年纯 JS 解决方案来检测自动填充的任何人,都可以。
请原谅标签错误,不能让它很好地放在 SO
//Chose the element you want to select - in this case input
var autofill = document.getElementsByTagName('input');
for (var i = 0; i < autofill.length; i++)
//Wrap this in a try/catch because non webkit browsers will log errors on this pseudo element
try
if (autofill[i].matches(':-webkit-autofill'))
//Do whatever you like with each autofilled element
catch(error)
return(false);
【讨论】:
【参考方案22】:有一个技巧可以理解浏览器是否填充输入(布尔值):
const inputEl = inputRef.current; // select the el with any way, here is ReactJs ref
let hasValue;
try
hasValue = inputRef.current.matches(':autofill');
catch (err)
try
hasValue = inputRef.current.matches(':-webkit-autofill');
catch (er)
hasValue = false;
// hasValue (boolean) is ready
在最后一个花括号之后,hasValue
就可以使用了。您能够检测到浏览器自动填充是否发生。
【讨论】:
【参考方案23】:我在用户名上使用了 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 事件的方式不同。我的解决方案简单易读,适用于较难编写代码的浏览器之一。 我最终得到了相同的解决方案:blur
事件。我对change
和blur
事件应用了相同的功能,效果很好。无需额外库的简单解决方案。【参考方案24】:
我遇到了同样的问题,我已经写了这个解决方案。
页面加载时,它开始轮询每个输入字段(我设置了 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);
);
【讨论】:
【参考方案25】:如果您只想检测是否使用了自动填充,而不是准确检测何时以及使用了哪个字段自动填充,您可以简单地添加一个将自动填充的隐藏元素,然后检查这是否包含任何值。我知道这可能不是很多人感兴趣的。将输入字段设置为负的 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';
将此输入附加到表单并在表单提交时检查其值。
【讨论】:
【参考方案26】:确实似乎是一个不依赖轮询的解决方案(至少对于 Chrome)。这几乎是骇人听闻的,但我确实认为比全球民意调查要好一些。
考虑以下场景:
用户开始填写字段1
用户选择一个自动填充字段 2 和字段 3 的自动完成建议
解决方案:在所有字段上注册一个 onblur,通过以下 jQuery sn-p $(':-webkit-autofill') 检查是否存在自动填充字段
这不会立即生效,因为它会延迟到用户模糊 field1,但它不依赖于全局轮询,因此 IMO,这是一个更好的解决方案。
也就是说,由于按回车键可以提交表单,因此您可能还需要相应的 onkeypress 处理程序。
或者,您可以使用全局轮询来检查 $(':-webkit-autofill')
【讨论】:
【参考方案27】:根据我的个人经验,下面的代码在 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();
);
【讨论】:
【参考方案28】:我在 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) ...);我已经收到所有字段的自动填充值。 可能是新版本?【参考方案29】:我的解决办法是:
$.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 毫秒。因此,当浏览器在第二个 10*1000=1sec 期间填充自动填充值时,将调用传递给自动填充的回调。在当前示例中,它只是添加了一个类。如果您还有更多问题,请不要犹豫,直接问:)。【参考方案30】:经过研究,问题是 webkit 浏览器不会在自动完成时触发更改事件。我的解决方案是自己获取webkit添加的自动填充类并触发更改事件。
setTimeout(function()
if($('input:-webkit-autofill').length > 0)
//do some stuff
,300)
这里是铬问题的链接。 https://bugs.chromium.org/p/chromium/issues/detail?id=636425
【讨论】:
以上是关于检测浏览器自动填充的主要内容,如果未能解决你的问题,请参考以下文章