动态修改iframe高度,从而自适应内容真实高度

5 篇文章 0 订阅
1 篇文章 0 订阅

项目中遇到这样的情况,需要用到iframe,iframe中的内容也是自己写的页面,由于页面中元素是异步加载出来的,并不能提前预知其高度,这样就不能设置iframe的高度,导致iframe会出现滚动条,用户体验不好。所以我需要能根据内容动态改变iframe的高度。

dom结构如下

<!-- iframe -->
<iframe id="iframe" scrolling="no" src="./iframe/page"></iframe>

<!-- ./iframe/page页 -->
<div id="main">
    // 异步加载的dom
</div>

一、setInterval

利用 setInterval 循环计算内容高度,然后给iframe重新设置,这样有缺点,无法得知什么时候才加载完毕,定时器需要一直执行,虽然对性能影响很小,但是不建议这样写。

setInterval(() => {
    const iframe = window.frameElement;
    const main= iframe?.contentWindow?.document?.querySelector('#main');
    iframe.height = main?.scrollHeight + 10;
}, 200)

二、DOMNodeInserted

DOMNodeInserted事件是监听dom节点中有新增节点,当内容有新元素插入时,重新设置iframe高度,如果dom结构过于复杂,事件会频繁触发,此时可以配合防抖函数,设置时间为200ms

import debounce from 'lodash/debounce';

// ...

document.querySelector('#main).addEventListener('DOMNodeInserted', debounce(resize, 200), false);

测试过程中发现,页面中第三方插件包含canvas,而且canvas绘制比较缓慢,会偶然出现canvas不能完整显示的情况。具体原因未知,怀疑是canvas绘制过程中修改了大小。

三、ResizeObserver

ResizeObserver 接口可以监听到 Element 的内容区域或 SVGElement的边界框改变。内容区域则需要减去内边距padding。(有关内容区域、内边距资料见盒子模型 )

ResizeObserver避免了在自身回调中调整大小,从而触发的无限回调和循环依赖。它仅通过在后续帧中处理DOM中更深层次的元素来实现这一点。如果(浏览器)遵循规范,只会在绘制前或布局后触发调用。

最后发现ResizeObserver,这是一个实验中的api,但是根据MDN的介绍,兼容性满足用户群体的日常使用。

ResizeObserver可以监听dom大小变化,正适合这种场景下使用,具体api的使用方法这里就不赘述了,可以参考其他资料。下面是我最后的逻辑:

  useEffect(() => {
    const resizeObserver = new ResizeObserver((entries) => {
      for (const entry of entries) {
        resize(entry.contentRect.height);
      }
    });
    resizeObserver.observe(document.querySelector('#main'));
    return () => {
      resizeObserver.disconnect();
    };
  }, []);

  function resize(height) {
    const iframe = window.frameElement;
    iframe.height = height + 10;
  }

 初始化时增加监听,每次观测到目标dom大小变化时,重新设置iframe高度。由于监听只会在绘制前或布局后触发调用,所以不必考虑频繁触发,经测试,在一次渲染中,触发频率很低。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现 iframe动态自适应高度,可以使用以下方法: 1. 使用 JavaScript 监听 iframe 内容的完成事件,然后动态设置 iframe高度。这样可以确保在内容加载完成后再调整高度。你可以使用以下代码: ```javascript var iframe = document.getElementById('your-iframe-id'); // 监听 iframe 内容加载完成事件 iframe.addEventListener('load', function() { // 设置 iframe高度内容高度 iframe.style.height = iframe.contentWindow.document.body.scrollHeight + 'px'; }); ``` 这样,当 iframe 内容加载完成后,会自动调整 iframe高度以适应内容。 2. 如果 iframe 内容来自同源的页面,你还可以使用 postMessage API 来进行跨域通信。在 iframe 内容页面中,将内容高度通过 postMessage 发送给父页面。然后在父页面中,使用 JavaScript 监听 message 事件,并根据接收到的高度值来设置 iframe高度。以下是一个简单的示例: 在 iframe 内容页面: ```javascript // 获取内容高度 var height = document.body.scrollHeight; // 发送高度给父页面 parent.postMessage(height, '*'); ``` 在父页面: ```javascript var iframe = document.getElementById('your-iframe-id'); // 监听 message 事件 window.addEventListener('message', function(event) { // 接收到消息后设置 iframe高度 iframe.style.height = event.data + 'px'; }); ``` 这样,当 iframe 内容页面发送消息时,父页面会接收到消息并设置 iframe高度。 以上是两种常用的方法来实现 iframe动态自适应高度。根据你的具体需求和情况,选择适合的方法来实现即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值