浏览器记住用户名和密码并且自动填充怎么破?百度找的方法好像都不够优雅,优雅永不过时,今天我就带你优雅的解决这个问题。
1. 现象
在浏览器中输入用户名和密码,浏览器会记住,下次再输入的时候,浏览器会自动填充,这个自动填充搞一个黄不拉几的背景色(chrome黄不拉几,Edge不是),而且还给自己精心写的输入框的样式覆盖了,真是头大。
让用户清除缓存?让用户手动删除记住的密码?这你还能控制用户?
前面的两个方案可以不用看,只当是拓展阅读,可以直接看最后的解决方案。
2. 解决方案1
万能的百度,找到了一个方法,就是在输入框的属性上加上autocomplete="off"
。
<input type="text" name="username" autocomplete="off"/>
这个方法很棒,来看看这个属性的说明:
- autocomplete
- 该属性规定是否启用浏览器的自动完成功能。如果启用,浏览器会自动完成输入字段的值。
- 该属性仅适用于 type="text"、type="search"、type="url"、type="tel"、type="email" 和 type="password"。
- 该属性值可选值:
- on:启用自动完成功能。
- off:禁用自动完成功能。
- new-password:启用自动完成功能,但是仅在用户输入新密码时使用。
- current-password:启用自动完成功能,但是仅在用户输入当前密码时使用。
- username:启用自动完成功能,但是仅在用户输入用户名时使用。
- email:启用自动完成功能,但是仅在用户输入电子邮件地址时使用。
- tel:启用自动完成功能,但是仅在用户输入电话号码时使用。
- ...还有很多,不一一列举了,可以去MDN查看。
- 默认值:on。
但是大家在使用这个方法时候发现好像并没有生效,所以这里标一个重点:
在大多数现代浏览器中, autocomplete 设置为 "off" 不会阻止密码管理器询问用户是否要保存用户名和密码信息,或者自动在网站的登录表单中填写这些值
气不气,这个属性只是禁止了浏览器弹出自动填充的下拉选项,但是并没有禁止密码管理器询问用户是否要保存用户名和密码信息,或者自动在网站的登录表单中填写这些值。
上面在列举属性值的时候,有一个属性值是new-password
,这个属性值是用来禁止密码管理器询问用户是否要保存用户名和密码信息,或者自动在网站的登录表单中填写这些值的。
查找解决方案的时候发现也有说到这个,但是依然没有生效:
<input type="password" name="password" autocomplete="new-password"/>
所以这里也标一个重点:
autocomplete="new-password" 这会告诉浏览器,不要为了以后在类似表单上自动填充而保存用户输入的数据。但浏览器不一定遵守。
想砸键盘的冲动都有了,阿西吧,这个属性到底有什么用呢?
3. 解决方案2
通过使用多个<input>
标签来实现,使用障眼法,让浏览器的自动填充填不到我们的目标输入框中。
<input type="text" name="username" autocomplete="off"/>
<!-- 这里就是障眼法 -->
<input type="text" name="username-hide" autocomplete="off" hidden/>
<input type="password" name="password-hide" autocomplete="off" hidden/>
<input type="password" name="password" autocomplete="off"/>
这种方法的原理是,在我们目标的两个<input>
标签之间插入两个隐藏的<input>
标签,这样浏览器就会自动填充到隐藏的<input>
标签中,而不会填充到我们目标的<input>
标签中。
限制性也很强,这两个标签必须放到我们目标的两个<input>
标签之间,很影响我们的布局,但是这个方法是目前为止最有效的方法了,除了不够优雅,没有其他的缺点了。
4. 解决方案3
这个就是我今天给到大家的解决方案,通过伪类:autofill
来实现。
先来认识一下这个伪类,这个伪类匹配到的元素是浏览器自动填充的元素,通常作用于<input>
标签。
input:-webkit-autofill {
/* 这里写你的样式 */
}
input:autofill {
/* 这里写你的样式 */
}
为了更好的兼容性,我们可以使用-webkit-autofill
这个伪类,而autofill
这个伪类并不是所有的浏览器都支持的,所以我们需要同时使用这两个伪类。
当然这个方法也是有缺陷的,还是因为浏览器的问题:
input:-webkit-autofill {
background-color: transparent !important;
background-image: none !important;
color: #000 !important;
}
上面这三个属性设置无效,哪怕加上了!important
也是无效的,因为浏览器设置的默认样式也是加上了!important
的。
浏览器对于默认填充的这三个属性是无法修改的,所以我们只能通过其他的方式来修改这三个属性。
input:-webkit-autofill {
-webkit-text-fill-color: #000 !important;
-webkit-box-shadow: 0 0 0 1000px #fff inset !important;
}
这里我们使用了-webkit-text-fill-color
这个属性来修改字体颜色,使用了-webkit-box-shadow
这个属性来修改背景颜色。
现在我们可以使用这个伪类先将字体颜色设置成透明,这样自动填充的字体就看不见了,这样就相当于没有自动填充:
input:-webkit-autofill {
-webkit-text-fill-color: transparent !important;
}
但是自动填充的内容还是在的,所以第二步我们需要将自动填充的内容清空:
setTimeout(() => {
const aotufills = document.querySelectorAll('input:-webkit-autofill');
aotufills.forEach((item) => {
item.style.color = '';
item.value = '';
});
}, 20)
这里我们使用了setTimeout
来延迟执行,因为我们需要等待浏览器自动填充完成之后再执行,否则获取不到自动填充的内容。
完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>解决浏览器自动填充样式问题</title>
<style>
input {
width: 200px;
height: 30px;
border: 1px solid #000;
margin: 10px 0;
}
input:-webkit-autofill {
-webkit-text-fill-color: transparent !important;
}
</style>
</head>
<body>
<input type="text" name="username" id="username" placeholder="请输入用户名">
<input type="password" name="password" id="password" placeholder="请输入密码">
<script>
setTimeout(() => {
const aotufills = document.querySelectorAll('input:-webkit-autofill');
aotufills.forEach((item) => {
item.style.color = '';
item.value = '';
});
}, 20)
</script>
</body>
</html>
这种方法也是有缺陷的,因为浏览器的兼容性问题,目前并不普及,所以网上没有使用这个方法的解决方案,后面跟着浏览器的更新,这个方案也会越来越普及。