根本原因是 form.val() 只在当前页面上下文生效,iframe 是独立文档环境,父页的 layui form 实例不可见;子页需自行加载 layui.form 模块、确保 dom 渲染完成、正确设置 lay-filter、显式调用 form.render('radio') 才能正常取值。

iframe 里调 form.val() 返回空对象或 undefined
根本原因是 form.val() 只在当前页面上下文生效,而 iframe 是独立文档环境,父页的 layui form 实例完全不可见。你在 iframe 里直接写 form.val('demoForm'),但这个表单 DOM 和模块实例都在子页自己内部——前提是子页已正确加载并初始化了 layui.form。
常见错误现象:子页 HTML 里写了 lay-filter="demoForm",也引入了 layui,但 form.val('demoForm') 仍返回空对象。
- 检查子页是否执行了
layui.use(['form'], function(form){...}),没加载模块就调用form.val()会静默失败(不是报错) - 确认表单 DOM 已渲染完成再取值,比如把取值逻辑放在
layui.ready()或$(document).ready()里 -
lay-filter值必须和form.val()的第一个参数完全一致(大小写敏感、无空格) - radio 必须嵌套在
<form class="layui-form"></form>容器内,且每个input[type="radio"]共享同一个name属性
子页 radio 渲染后仍取不到选中值
layui 不会自动监听初始 HTML 中的 checked 属性,哪怕你写了 <input type="radio" name="status" value="1" checked>,form.val() 也不会识别——它只响应渲染后由 layui 管理的状态。
必须显式调用 form.render('radio', 'demoForm')(第二个参数是 lay-filter 值),否则所有取值操作都基于未接管的原始 DOM 状态。
- 动态插入的 radio(比如 JS 拼接后 append 到页面),插入完立刻执行
form.render('radio', 'demoForm') - 如果只渲染 radio,不传第二个参数也能生效,但建议带上,避免意外影响其他表单
- 不要依赖浏览器原生
change事件监听 radio,layui 的点击行为不触发原生 change;改用form.on('radio(demoForm)', function(data){...})
父页想从 iframe 里读 radio 值,别直接 DOM 查询
父页用 document.getElementById 或 document.querySelector 查不到 iframe 内部的元素,这是同源策略和文档隔离决定的。强行用 layer.getChildFrame('body', index).find('input[name="status"]:checked').val() 也容易失败——因为 jQuery 对象可能没加载,或子页还没 render 完。
- 确保子页已加载完成:在父页
success回调里延时操作(如setTimeout(..., 200)),或监听子页postMessage - 子页主动传值最可靠:用户选择后,子页立即执行
parent.receiveRadioValue({ status: '1' }),父页提前定义好该函数 - 若必须父页拉取,先等子页 ready:
var body = layer.getChildFrame('body', index); body.find('input[name="status"]:checked').val(),但前提是子页已调用form.render() - 跨域 iframe 下,
getChildFrame直接失效,只能靠postMessage通信
禁用状态下的 radio 怎么取值
disabled 的 radio 默认不会被 form.val() 采集,也不会触发 form.on('radio(...)') 事件。这不是 bug,是 layui 的设计行为——它模拟表单提交逻辑,而 disabled 字段本就不参与提交。
- 若业务需要读取 disabled radio 的值,改用原生方式:
document.querySelector('input[name="status"][disabled]:checked')?.value - 或者把
disabled改成readonly(对 radio 无效,但可配合 CSS 视觉禁用 + 移除 click 事件) - 更稳妥的做法是:禁用前先把值存到 data 属性或全局变量,后续直接读那个缓存
form.val() 越容易出问题——它依赖一整套初始化链路:模块加载 → DOM 就绪 → lay-filter 绑定 → form.render() 触发 → 用户交互。漏掉任意一环,值就“消失”了,而且不报错。真正要命的是,这些环节全得在 iframe 自己内部闭环完成,父页插不上手。











