layui input 默认聚焦需在 form.render() 完成后的微任务中执行,推荐 settimeout(() => {el.focus()}, 0);弹窗中须在 layer.open 的 success 回调里操作;确保 id 唯一或用 name 精准定位;移动端需防 focus 失效,可加 select() 辅助唤起键盘。

layui input 默认焦点必须等 form.render() 完成后操作
直接在 layui.use(['form'], function(){}) 回调里写 document.getElementById('xxx').focus() 大概率失败。因为 Layui 的表单组件(尤其是带 lay-key 或经过 form.render() 初始化的)会重写 DOM 结构,原始 input 可能被包裹、隐藏或尚未挂载到可视文档流中。焦点必须在渲染完成后的微任务时机触发。
- 用
setTimeout(() => { ... }, 0)是最通用且稳定的做法,确保 DOM 已就绪 - 不要依赖
layui.form.on('render')—— 这不是官方暴露的事件,行为不可靠 - 如果 input 在弹窗(
layer.open)里,必须放在success回调中执行,不能放外面 - 确保目标元素有明确的
id或可通过name唯一定位,避免多个同名 input 导致getElementById取错
layer.open 弹窗中聚焦 input 要防跨域和加载时序问题
当 layer.open 的 type: 2(iframe)时,父页 JS 无法直接访问子页 DOM:跨域报错,同域也常因 iframe 加载未完成而取不到元素。强行用 layer.getChildFrame().find() 属于 jQuery 时代的老写法,Layui 2.8+ 不再推荐,且极易失败。
- 正确做法是把聚焦逻辑写在子页面内部,而不是父页
- 子页中先调用
form.render('input'),再document.getElementById('xxx').focus() - 加
setTimeout(..., 100)微调时机,防极快渲染下 DOM 尚未完全可交互 - 移动端 Safari 对
focus()支持更苛刻,建议前置判断:if ('ontouchstart' in window) return;
动态表单反复打开时,id 冲突和重复绑定是高频雷区
编辑多条数据时反复打开同一弹窗,若所有 input 都用相同 id="username",getElementById 永远只取第一个,后续打开的弹窗必然聚焦失败。同时,若每次打开都重新绑定事件(比如清除图标点击后聚焦),不清理旧监听会导致多次 focus 触发。
- input 的
id必须唯一,推荐拼接数据 ID:id="username-123" - 用
document.querySelector('input[name="username"]')替代getElementById,更健壮(前提是 name 唯一) - 如果用 jQuery 绑定清除图标事件,务必先
.off('click')再.on('click') - 聚焦前检查
el.disabled === false && el.readOnly === false,否则focus()无效且无提示
移动端自动唤起键盘需额外兜底
部分安卓 WebView 或 iOS Safari 下,即使调用了 focus(),软键盘也不弹出——这是浏览器策略限制,非代码 bug。尤其在页面刚加载、弹窗异步插入等场景下更明显。
- 可在
success回调中补一手elem.focus(); elem.select();(select()有时能触发键盘) - 更稳但略重的方式:改用
layer.open({ type: 1, content: $('#form') }),自定义 content,控制 input 生命周期 - 鸿蒙等新平台另有
defaultFocus(true)属性,但 Layui 不适用,别混用 - 别在
ready钩子外操作 input,Layui 的 DOM 插入是异步的,早于它操作就是白忙
.focus(),实际卡在渲染时序、DOM 结构、移动端策略、动态复用四个维度上。漏掉任意一个,都会表现为“代码写了,但没反应”。











