已实现单个iframe自适应,如何解决两个iframe自动尺寸调整失效问题?
多iframe自动高度调整的问题排查与实现方案
原有两种尝试的失效原因
- 重复设置相同id的方案失效:HTML规范要求页面内的id值必须全局唯一,
document.getElementById()方法只会返回文档结构中第一个匹配对应id的元素,后续的同名元素完全无法被选中,自然绑定不上高度调整逻辑。 - 分设独立id、编写两段独立脚本的方案失效:两段脚本都使用全局作用域下的同名变量
iframe存储选中的元素,由于var声明的变量会被提升到全局作用域,第二次选中iframe2时会直接覆盖之前存储的iframe1引用。而绑定的onload回调中引用的就是这个全局变量,等iframe1加载完成触发回调时,全局变量已经被指向iframe2,导致回调实际操作的是iframe2而非自身,最终表现为iframe1没有任何高度调整效果。
可行的实现方案
方案1:通过类选择器批量绑定,适配多iframe场景
给所有需要自动调整高度的iframe设置相同的class属性,比如auto-height-iframe,再通过一段通用遍历逻辑完成事件绑定,从根源上避免id重复和变量覆盖的问题:
<!-- HTML部分 --> <iframe class="auto-height-iframe" src="https://www.mywebsite.com/iframed1" scrolling="no"></iframe> <iframe class="auto-height-iframe" src="https://www.mywebsite.com/iframed2" scrolling="no"></iframe>
// 脚本部分 const iframes = document.querySelectorAll('.auto-height-iframe'); iframes.forEach(iframe => { iframe.onload = function() { // *用事件触发的this指代当前iframe元素,完全不受外部变量覆盖的影响* this.style.height = this.contentWindow.document.body.scrollHeight + 'px'; } });
这种方案扩展性更好,后续新增自动高度的iframe只需要加上对应的class,不需要重复编写绑定逻辑。
方案2:使用独立id绑定的修正写法
如果必须给每个iframe设置独立id,只需要保证变量作用域独立,避免同名变量互相覆盖即可:
<iframe id="iframe1" src="https://www.mywebsite.com/iframed1" scrolling="no"></iframe> <iframe id="iframe2" src="https://www.mywebsite.com/iframed2" scrolling="no"></iframe> <script> // 为每个iframe设置独立的变量名,使用块级作用域的const声明 const autoFrame1 = document.getElementById('iframe1'); autoFrame1.onload = function() { this.style.height = this.contentWindow.document.body.scrollHeight + 'px'; } const autoFrame2 = document.getElementById('iframe2'); autoFrame2.onload = function() { this.style.height = this.contentWindow.document.body.scrollHeight + 'px'; } </script>
注意脚本要放在页面DOM元素的下方执行,避免因为DOM未加载完成选不到对应元素。
边界注意事项
- 只有当iframe加载的内容和父页面属于同域时,才能通过
contentWindow读取iframe内部的文档高度,如果是跨域资源,会被浏览器同源策略拦截,无法通过该方法获取高度值。 - 如果iframe内部存在动态加载的内容(比如异步渲染模块、展开折叠内容导致高度变化),仅靠onload事件无法覆盖所有高度变化场景,需要在iframe内部通过postMessage向父页面实时传递最新高度值,再更新对应iframe的样式。
内容的提问来源于stack exchange,提问作者robert0
相关产品推荐
相关产品推荐

