mutationobserver 必须放在子页面中,因父页无法访问跨域 iframe 的 contentdocument,否则触发 securityerror;子页用它监听 dom 变化并 postmessage 通知父页更新高度。

跨域 iframe 无法直接读取子页面 DOM,所以 MutationObserver 不能单独在父页使用来监听子页变化——它只能观察自身文档树。但 MutationObserver 可以作为子页面内部的高度同步辅助手段,配合 postMessage 实现更精准、低延迟的高度适配。关键在于:把 MutationObserver 放在子页面里,监测自身内容变动,再主动通知父页。
为什么 MutationObserver 要放在子页面里
父页面对跨域 iframe 的 contentDocument 没有访问权限,任何试图用 iframe.contentDocument + MutationObserver 的方案都会触发 SecurityError。真正可行的路径是:
- MutationObserver 运行在子页面上下文中,可自由监听
document.body或根容器的结构/样式变化 - 一旦检测到高度可能变化(如 DOM 增删、图片加载完成、CSS 动画结束),立即计算新高度
- 通过
window.parent.postMessage()将高度值发给父页 - 父页仅需监听 message 事件并更新 iframe.style.height
子页面中用 MutationObserver 监听并上报高度
以下代码放在子页面(跨域)的 <script></script> 中,确保在 DOM 加载后执行:
const observer = new MutationObserver(() => {
// 清除旧 height 避免 margin 折叠干扰
document.body.style.height = 'auto';
document.documentElement.style.height = 'auto';
const height = Math.max(
document.body.scrollHeight,
document.documentElement.scrollHeight,
document.body.offsetHeight,
document.documentElement.offsetHeight
);
window.parent.postMessage({
type: 'iframeResize',
height: height + 'px'
}, 'https://your-parent-domain.com'); // 替换为父页真实域名
});
// 开始监听 body 及其后代节点的添加、删除、属性变更(含 class、style)
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['class', 'style', 'src', 'data-src']
});
// 补充:监听图片加载完成(常见高度突变原因)
const imgObserver = new MutationObserver(records => {
records.forEach(r => {
r.addedNodes.forEach(node => {
if (node.tagName === 'IMG' && node.complete) {
setTimeout(() => observer.takeRecords(), 0);
}
});
});
});
imgObserver.observe(document.body, { childList: true, subtree: true });
父页面安全接收并应用高度
父页只需做两件事:校验来源、设置样式。不建议清空 height 后再赋值,直接覆盖更稳妥:
window.addEventListener('message', event => {
// ? 严格校验 origin,禁止用 '*' 上线
if (event.origin !== 'https://your-iframe-domain.com') return;
if (event.data.type === 'iframeResize') {
const iframe = document.getElementById('myIframe');
if (iframe) {
iframe.style.height = event.data.height;
iframe.style.minHeight = '1px'; // 防止 collapse
}
}
});
配合 onload 和 resize 提升鲁棒性
MutationObserver 很灵敏,但无法捕获初始渲染或窗口缩放。建议组合使用:
-
window.onload:首次加载完成后发一次高度 -
window.addEventListener('resize', ...):监听窗口大小变化(尤其响应式布局) - MutationObserver:应对内容动态插入、AJAX 渲染、懒加载等场景
三者互补,覆盖绝大多数跨域 iframe 高度变化时机。不需要轮询,也不依赖第三方库,原生 JS 即可落地。











