动态修改iframe高度,从而自适应内容真实高度 |
您所在的位置:网站首页 › iframe的高度怎么设置 › 动态修改iframe高度,从而自适应内容真实高度 |
项目中遇到这样的情况,需要用到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) 二、DOMNodeInsertedDOMNodeInserted事件是监听dom节点中有新增节点,当内容有新元素插入时,重新设置iframe高度,如果dom结构过于复杂,事件会频繁触发,此时可以配合防抖函数,设置时间为200ms import debounce from 'lodash/debounce'; // ... document.querySelector('#main).addEventListener('DOMNodeInserted', debounce(resize, 200), false);测试过程中发现,页面中第三方插件包含canvas,而且canvas绘制比较缓慢,会偶然出现canvas不能完整显示的情况。具体原因未知,怀疑是canvas绘制过程中修改了大小。 三、ResizeObserverResizeObserver 接口可以监听到 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 |