目录

背景

实现方式

实现思路

实现代码

扩展场景

参考文档


背景

在日常开发中会遇到一种情况,就是页面需要嵌套iframe,由于iframe无法自适应里面样式高度,所以我们需要去监听iframe的动态高度

实现方式

MutationObserver

实现思路

  • 定义观察器MutationObserver
  • 监听iframe的contenWindow的DOMContentLoaded事件(当初始的 HTML 文档被完全加载和解析完成)
  • 当iframe的contentWindow.document.readyState 为interactive(代表文档已被解析,正在加载样式资源等等)开始监听 observer.observe(iframeEle.contentWindow.document, options);
  • iframe内部的dom动态更新,观察器捕获到dom变化,此时可以拿到contentWindow.document.body.scrollHeight,给外层的iframe元素赋值高度

实现代码

话不多说,直接上代码

需要监听的iframe

<iframe id="iframeId" src="xxxxx"></iframe>
let iframeEle = document.getElementById('iframeId');

// 配置监听方法的属性值
const options = {
    "childList" : true,
    "attributes" : false,
    "characterData" : false,
    "subtree" : true,
    "attributeOldValue" : false,
    "characterDataOldValue" : false
};
// 定义一个监听器
var observer = new MutationObserver((mutations) => {
      let is_dom_change = false;
      mutations.forEach((item) => {
        if (item.type === 'childList') {
          is_dom_change = true;
        }
      });
      const scrollHeight = iframeEle.contentWindow.document.body.scrollHeight;
      if (is_dom_change) {
        iframeEle.style.height = `${scrollHeight}px`;
      }
});


iframeEle.contentWindow.addEventListener('DOMContentLoaded', function(e) {
    try {
        if (iframeEle.contentWindow.document.readyState === "interactive") {
            // 传入监听的dom,以及配置
            observer.observe(iframeEle.contentWindow.document, options);
        }
    } catch (err) {}
});

扩展场景

当iframe内部链接发生变化,或者是后端或者网关重定向页面,如何去获取最新的iframe里面的href?

有人可能会说用onload方法,例如

<iframe onload="handleOnload" id="iframeId"></iframe>

<script>
handleOnload(e) {
    console.log('触发了onload事件');
}
</script>

但实际使用就会发现,在某些特定的时刻iframe的onload事件只会触发一次。

对此我们可以去监听iframe的load方法,并且在iframe第一次加载完之后开始监听,保证代码的健壮性

let iframeId = document.getElementById("iframeId")


iframeEle.contentWindow.addEventListener('DOMContentLoaded', function(e) {
    try {
        if (iframeEle.contentWindow.document.readyState === "interactive") {
            iframeId.addEventListener("load", function(e) {
                // 拿到iframe内部最新的href
                console.log(iframe.contentWindow.location.href)						
            });
        }
    } catch (err) {}
});

参考文档

DOMContentLoaded - Web API 接口参考 | MDN

document.readyState - Web API 接口参考 | MDN

MutationObserver - Web API 接口参考 | MDN

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐