1.原生 JS 实现(同域场景),通过监听 iframe 加载事件,读取其内部文档高度并动态调整容器高度,无需额外依赖。
实现步骤:
模板定义:在组件中添加 iframe 并绑定 ref 和 load 事件
高度计算:通过 contentWindow.document 获取 iframe 内容高度
延迟执行:使用 setTimeout 确保内容加载完成后再计算高度
示例代码:
<template>
<div class="iframe-container">
<iframe
ref="iframe"
:src="iframeSrc"
frameborder="0"
width="100%"
scrolling="no"
@load="handleIframeLoad"
></iframe>
</div>
</template>
<script>
export default {
data() {
return {
iframeSrc: 'http://baidu.com' // 同域页面路径
};
},
methods: {
handleIframeLoad() {
// 延迟 1000ms 确保内容完全加载
setTimeout(() => {
this.resetHeight();
}, 1000);
},
resetHeight() {
const iframe = this.$refs.iframe;
if (!iframe) return;
try {
// 获取 iframe 内部文档高度(兼容不同浏览器)
const bodyHeight = iframe.contentWindow.document.body.scrollHeight;
const htmlHeight = iframe.contentWindow.document.documentElement.scrollHeight;
const maxHeight = Math.max(bodyHeight, htmlHeight);
// 额外添加 150px 缓冲高度
iframe.style.height = `${maxHeight + 150}px`;
} catch (e) {
// 跨域时会抛出异常,需使用方案二
console.error('跨域访问被阻止,请使用 iframe-resizer 插件');
}
}
}
};
</script>
2.使用 iframe-resizer 插件(跨域/复杂场景)
iframe-resizer 是专门解决 iframe 自适应问题的库,支持跨域通信和动态内容变化监听,比原生方案更健壮。
实现步骤:
引入插件:主页面和嵌入页面分别引入对应脚本
初始化配置:在主页面调用 iFrameResize 方法
嵌入页配置:引入内容窗口脚本,无需额外代码
示例代码:
主页面
<template>
<div class="iframe-container">
<iframe
ref="iframe"
src="http://baidu.com"
frameborder="0"
width="100%"
scrolling="no"
></iframe>
</div>
</template>
<script>
export default {
mounted() {
// 确保插件已加载(可在 public/index.html 中全局引入)
if (window.iFrameResize) {
// 初始化插件,配置跨域支持
window.iFrameResize({
log: false, // 生产环境关闭日志
checkOrigin: false, // 允许跨域
autoResize: true, // 内容变化时自动调整
heightCalculationMethod: 'bodyOffset' // 高度计算方式
}, this.$refs.iframe);
}
}
};
</script>
嵌入页面,在被嵌入的 页面中引入内容窗口脚本:
<!-- 嵌入页面头部 -->
<script src="https://cdn.jsdelivr.net/npm/iframe-resizer@4.3.2/js/iframeResizer.contentWindow.min.js"></script>
<div class="dynamic-content">
<!-- 动态加载的内容 -->
</div>
核心原理:主页面通过 iframeResizer.min.js 监听消息,嵌入页面通过 iframeResizer.contentWindow.min.js 主动发送尺寸信息,实现跨域通信和实时调整。