客户把一个报名表单嵌进我们的页面,iframe 高度写死 600px。表单加了新字段后,底部提交按钮被裁掉一截,用户点不到。这事得让 iframe 自己长高。
先分情况。iframe 里的页面和父页面同一个域名,属于同源,父页面能直接读子页面的文档高度。跨域就不行,浏览器会拦,只能用 postMessage 通信。
同源:读 scrollHeight 就够了
子页面加载完成后,取 documentElement.scrollHeight 或 body.scrollHeight,赋给 iframe 的 height。取两者最大值更保险,不同浏览器表现不一样。
光在 onload 里算一次不够。表单展开、图片加载、字体渲染都会让高度变化。用 ResizeObserver 监听子页面 body,尺寸一变就重新设置,比定时器轮询省资源。
跨域:让子页面主动报高度
在 iframe 页面里,用 ResizeObserver 监听自身高度,变化时调用 parent.postMessage,把高度传出去。父页面监听 message 事件,先校验来源,再设置高度。
window.parent.postMessage({ height: document.body.scrollHeight }, targetOrigin);targetOrigin 别写星号,写具体域名。写星号等于把消息广播给任何父页面,别人嵌套你的页面也能收到。
CSS 那两个 100% 的坑
给 iframe 设 height 100%,得先保证它的父元素有确定高度。父元素是 auto,百分比就没有参照,最后算出来是 0。链条上任何一层断了,都不生效。
移动端还有 vh 的问题。手机浏览器地址栏收起展开会改变视口高度,100vh 会跳。用 dvh 或者干脆用 JS 算。
最后一句,高度自适应做完了,记得给个最小高度,避免内容还没加载时页面塌成一条线。