表单自动填充失效主因是autocomplete属性值不标准或缺失,必须使用浏览器认可的标准关键词(如name、email、tel等),且密码字段需配对使用current-password和new-password。
表单自动填充失效,
属性没起作用
浏览器不记你填过什么,不是它“懒”,而是
值写错了或缺失。这个属性是唯一被主流浏览器(Chrome、Firefox、Safari)共同尊重的表单记忆开关,但它的值必须匹配标准关键词,比如
、
、
,不能随便写成
或留空。
常见错误:用自定义值(如
)代替标准值(应为
)
姓名字段优先用
,而不是拆成
+
—— 后者虽规范,但部分浏览器识别率低
地址类字段(如省/市)要层级完整:
(省)和
(市)才可能被记住;单写
无效
密码字段必须配对出现:
和
,否则 Chrome 可能拒绝保存
用户改了偏好但刷新后还原,
没存对地方
靠 JS 手动存字段值到
是可行的,但容易在「什么时候读」「什么时候写」「要不要清空」三个节点出错。最常踩的坑是:只在表单提交时存,却没在页面加载时主动恢复;或者把整个表单序列化成字符串存,结果某个字段类型变了(比如从
改成
),取出来赋值就失败。
读取时机必须在 DOM 加载完成且表单元素存在之后,推荐用
或直接放在
标签末尾
不要用
存整个表单对象——它不包含用户输入值,要用循环遍历每个
的
属性单独存
敏感字段(如银行卡号、身份证号)别进
,浏览器本地存储无加密,且生命周期不可控
示例关键逻辑:
多步骤表单切换页后偏好丢失,
生命周期理解偏差
看似适合多步流程,但它按「标签页+顶级浏览上下文」隔离。用户新开一个标签页重新进入第二步,或从外链跳转进来,哪怕 URL 一样,
也是全新的。这不是 bug,是设计如此。
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
如果步骤间是纯前端路由(如 React Router、Vue Router),URL 不刷新,
可用;但只要发生真实页面跳转(
或点击 a 标签),就得换方案
替代方案只有两个:服务端暂存(需 session 或 JWT 支持),或改用
+ 显式清理机制(比如用户点「重填」时调用
)
别依赖
事件来存数据——现代浏览器限制该事件执行时间,且移动端基本不触发
Chrome 自动填充弹窗遮挡内容,
触发时机与 CSS 冲突
Chrome 在聚焦输入框时会强行在下方弹出建议列表,如果父容器有
、
或
层级混乱,弹窗就会被裁切或压在底层。这不是代码逻辑问题,是渲染层叠加规则导致的。
立即学习
“
前端免费学习笔记(深入)
”;
最简解法:给所有带
的
加
和足够高的
(如 1000)
避免对表单整体设
,尤其当它用于清除浮动时,改用
不用
(如
)微调表单位置——这会创建新层叠上下文,把 autocomplete 弹层锁死在旧层级里
测试时务必在无痕模式下操作,插件(尤其是密码管理器)可能劫持并覆盖原生 autocomplete 行为
表单记忆这事,核心就两条:浏览器原生能力靠
值是否标准,JS 手动兜底靠存取时机是否卡准。两者混用时,最容易忽略的是「用户手动修改后,原生 autocomplete 是否还继续生效」——Chrome 在检测到 JS 修改过 input 值后,有时会静默停用后续自动填充,得用
+
重新激活。
autocompleteautocompleteautocomplete="name"autocomplete="email"autocomplete="tel"autocomplete="user-phone"autocomplete="mobile"autocomplete="tel"autocomplete="name"given-namefamily-nameautocomplete="address-level1"autocomplete="address-level2"autocomplete="city"localStoragelocalStoragetextnumberDOMContentLoadedJSON.stringify(form)inputvaluelocalStoragedocument.querySelectorAll('input[data-persist]').forEach(el => {
const key = `form_${el.name}`;
if (localStorage.getItem(key)) {
el.value = localStorage.getItem(key);
}
el.addEventListener('input', () => localStorage.setItem(key, el.value));
});sessionStoragesessionStoragesessionStoragesessionStoragewindow.location.hreflocalStoragelocalStorage.removeItem()beforeunloadautocompleteoverflow: hiddentransformz-indexautocompleteinputposition: relativez-indexoverflow: hiddendisplay: flow-roottransformscale(0.99)autocompleteel.focus()el.select()