如何让 A 页面的宽高实时自适应 iframe 的宽高大小
一个 iframe,内嵌了一个 A 页面,iframe 的宽高不停变化,如何让 A 页面的宽高实时自适应这个 iframe 的宽高大小。请说出至少 3 种方法,越难越好。
参考答案:
补充
补充:让嵌入的 A 页面跟随外层 iframe 宽高自适应,本质是父页面把尺寸告诉子页面或子页面主动监听父页面尺寸。下面给出 3 种由易到难的方法。
方法一:CSS 设置 100% 宽高(最简单)
如果 A 页面就是普通 HTML,让它的根元素始终占满父容器即可:
/* A 页面 */
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
外层 iframe 改变宽高后,A 页面也会跟着撑满。缺点:只解决"铺满",解决不了 A 内部布局自适应。
方法二:postMessage 跨域通信(推荐)
父子之间通过 postMessage 传递尺寸,父页面在 onresize 时把新尺寸发给子页面。
父页面(host):
const iframe = document.getElementById('myFrame');
function sendSize() {
iframe.contentWindow.postMessage({
type: 'resize',
width: iframe.clientWidth,
height: iframe.clientHeight,
}, '*'); // 生产环境换成具体 origin
}
window.addEventListener('resize', sendSize);
iframe.addEventListener('load', sendSize);
子页面(A):
window.addEventListener('message', (e) => {
if (e.data && e.data.type === 'resize') {
document.documentElement.style.width = e.data.width + 'px';
document.documentElement.style.height = e.data.height + 'px';
// 触发内部布局重新计算
window.dispatchEvent(new Event('resize'));
}
});
注意跨域时 postMessage 的第二个参数应当是具体 origin,而不是 '*'。
方法三:同域下用 window.frameElement(最直接)
如果 A 页面与父页面同源,A 页面可以直接读取包裹它的 iframe 的尺寸:
function syncSize() {
const frame = window.frameElement; // 当前页面所在 iframe 元素
if (frame) {
document.documentElement.style.width = frame.clientWidth + 'px';
document.documentElement.style.height = frame.clientHeight + 'px';
}
}
syncSize();
window.addEventListener('resize', syncSize);
方法四(额外):父页面动态设置 iframe 高度以适应内容
反过来,如果要让 iframe 高度跟着 A 内容自适应,可以让 A 把自身高度通过 postMessage 告诉父页面,父页面再去改 iframe.style.height。
来源整理自:我的有道云笔记



