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

您所在的位置:网站首页 iframe的高度怎么设置 动态修改iframe高度,从而自适应内容真实高度

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

2023-12-21 23:48| 来源: 网络整理| 查看: 265

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

dom结构如下

// 异步加载的dom 一、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高度。由于监听只会在绘制前或布局后触发调用,所以不必考虑频繁触发,经测试,在一次渲染中,触发频率很低。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3