项目中经常会嵌入别人的页面,如果不知道被嵌入页面的高度,就没法给Iframe高度赋值,内部嵌入的页面就会出现滚动条,影响页面的美观。

1、如果被嵌入页面和当前页面不跨域,可以使用Iframe的@load加载事件获取内部高度

 <iframe   name="outerPage"  @load="iframeload()" :src="url" ref="iframe"  scrolling="auto" frameborder="0" id="outerPage" :style="{ 'min-width': '100%', 'min-height': '100%' }" ></iframe>

 在对应的加载事件里获取内部页面高度,最后将获取的高度赋值

 iframeload() {
      setTimeout(() => {
        try {
          const cIframe = document.getElementById("outerPage");
          let aWindow = cIframe.contentWindow;
          let aWindowHeight =
            aWindow .document.documentElement.scrollHeight ||
            aWindow .document.body.scrollHeight;
      
          let doc = cIframe.contentDocument || cIframe.document;
          let cHeight = Math.max(
            doc.body.clientHeight,
            doc.documentElement.clientHeight
          );
          let sHeight = Math.max(
            doc.body. scrollHeight,
            doc.documentElement.scrollHeight
          );
          let lheight = Math.max(cHeight, sHeight);
          let finalHeight = Math.max(lheight, aWindowHeight );
          this.iframeHeight = finalHeight + "px";
          
        } catch (e) {
          //跨域获取不到
          throw new Error("自定义错误setIframeHeight Error");
        }
      }, 1500);
    },

2、如果被嵌入页面和当前页面跨域,可以在子页面使用postMessage(),父页面接受该信息改变高度。

如果跨域且子页面的高度是固定的那么直接使用postMessage()。

//等子页面渲染好了之后,获取高度
let viewHeight = document.getElementById("mainF").clientHeight;
window.parent.postMessage(
          {
            code: "iframeheght",
            text: viewHeight
          },
          "*"
        );

如果跨域被嵌入内部的页面高度会变化。 

页面高度如果会变化,通常都是某个数据的变化,监听该数据的变化然后在其变化后获取高度。

由于数据变化到页面渲染完成会有一定的延时,理论上必须等待页面渲染完成才能获取之后的高度。但页面渲染完成的时间是无法确定的,例如数组的渲染,长度为2的数组渲染和长度为20 的数组渲染时间肯定不一致。因此当数据变化后,设置每400ms获取当前页面的高度(这是设置时间可以自己定),如果当前高度和上一次历史记录高度一致就post给父页面,重置父页面的高度,不一致就继续等待400ms.。

submit() {
      //每500ms获取当前页面的高度,如果当前高度和上一次历史记录高度一致就post给父页面,重置父页面的高度
      let viewHeight = document.getElementById("mainF").clientHeight;
      if (viewHeight !== this.currentPageHeight) {
    //上一次存下的历史页面高度
        this.currentPageHeight = viewHeight;
        setTimeout(() => {
          this.submit();
          console.log("延时viewHeight", viewHeight);
        }, 400);
      } else {
        window.parent.postMessage(
          {
            code: "iframeheght",
            text: viewHeight
          },
          "*"
        );
        console.log("viewHeight", viewHeight);
      }
    },

完整的代码如下

//子页面 
  submit() {
      //每500ms获取当前页面的高度,如果当前高度和上一次历史记录高度一致就post给父页面,重置父页面的高度
      let viewHeight = document.getElementById("mainF").clientHeight;
      if (viewHeight !== this.currentPageHeight) {
        this.currentPageHeight = viewHeight;
        setTimeout(() => {
          this.submit();
          console.log("延时viewHeight", viewHeight);
        }, 400);
      } else {
        window.parent.postMessage(
          {
            code: "iframeheght",
            text: viewHeight
          },
          "*"
        );
        console.log("viewHeight", viewHeight);
      }
    },
//父页面 
<template>
 <div
    class="iframe-container"
    id="iframe-container"
    :style="`height: ${iframeHeight};`"
  >
    <!-- @load="calAutoHeight"-->
    <iframe 
      :src="url"
      ref="iframe"
      scrolling="auto"
      @load="iframeload()"
      frameborder="0"
      id="outerPage"
      :style="{ 'min-width': '100%', 'min-height': '100%' }"
    ></iframe>
  
  </div>
  
</template>
<script>

export default {
  name: "iframePage",
  props: [],
  data() {    
    return {
      url: "",
      iframeHeight: "calc(100vh - 93px)"
    };
  },
 created() {
  },
  mounted() {
     window.addEventListener("message", this.iframeHeightBypostmessage);
  },
  beforeDestroy() {
    window.removeEventListener("message", this.iframeHeightBypostmessage);
  },
  computed: {
  },
  methods: {
    iframeHeightBypostmessage(e) {
     if (e&&e.data&&e.data.code === "iframeheght") {
       this.iframeHeight = e.data.text+"px";
        console.log( this.iframeHeight+"gggggggggggggggggg")
      }
   },
    iframeload() {
      setTimeout(() => {
        try {
          const cIframe = document.getElementById("outerPage");
          let a = cIframe.contentWindow;
          let b =
            a.document.documentElement.scrollHeight ||
            a.document.body.scrollHeight;
          console.log(b, "px");
          // cIframe.height=b+'px'
          let doc = cIframe.contentDocument || cIframe.document;
          let cHeight = Math.max(
            doc.body.clientHeight,
            doc.documentElement.clientHeight
          );
          let sHeight = Math.max(
            doc.body. ,
            doc.documentElement.scrollHeight
          );
          let lheight = Math.max(cHeight, sHeight);
          let finalHeight = Math.max(lheight, b);
          this.iframeHeight = finalHeight + "px";
           console.log(finalHeight, "px");
        } catch (e) {
             throw new Error("自定义错误setIframeHeight Error");
        }
      }, 1500);
    },
  
  }
};
</script>

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐