vue+ElementUI下iframe子頁面彈窗蒙層遮罩問題優化


一、問題描述

    在使用iframe時,子頁面的彈框遮罩只能覆蓋子頁面,而無法擴展到父頁面。(如下圖)

    

 

二、解決方案 

    0、前提:彈出的內容高度和寬度不能超過子頁面的范圍(否則會出現滾動條)

    1、父頁面:

    當子頁面需要彈框時,父頁面也彈出空彈框,使得整個頁面能夠遮罩,然后將子頁面的層級提高,使子頁面可以由子頁面自己控制。監聽子頁面發來的遮罩處理信號,如果是true,則將iframe的position變成absolute,zIndex設為較大的值10000;隱藏滾動條;彈出空的彈窗(設置點擊空白、按Esc鍵無法取消)。如果是false,則將position設為unset;關閉彈窗。

    (1)父頁面HTML

<template>
  <div class="parent" id="parentDiv">
    <template>
      <iframe
        ref="iframe"
        id="bdIframe"
        :src="src"
        width="100%"
        height="auto"
        scrolling="no"
        frameborder="0"
      ></iframe>
    </template>
    <el-dialog
      :visible.sync="dialogTableVisible"
      :close-on-press-escape="false"
      :close-on-click-modal="false"
    ></el-dialog>
  </div>
</template>

       (2)父頁面監聽子頁面處理彈框消息的JS

changeDialog(data) {
      //isDialog為子頁面彈框的開關
      this.dialogTableVisible = data.isDialog;
      if (data.isDialog) {
        //當子頁面彈框開時
        //父頁面外部滾動條隱藏
        document.getElementsByClassName("indexCon")[0].style.overflow = "hidden";
        //將子頁面iframe頁面層級提升
        document.getElementById("parentDiv").style.position = "relative";
        document.getElementById("bdIframe").style.position = "absolute";
        document.getElementById("bdIframe").style.zIndex = 10000;
      } else {
        //當子頁面彈框關時
        //恢復
        document.getElementsByClassName("indexCon")[0].style.overflow = "auto";
        document.getElementById("parentDiv").style.position = "unset";
        document.getElementById("bdIframe").style.position = "unset";
        document.getElementById("bdIframe").style.zIndex = "unset";
      }
    },

附上父頁面的滾動條監聽方法,在頁面較長時,需要修改子頁面的彈窗位置。

(3)父頁面拋出滾動條監聽

    sendMassage(data) {
      let bdIframe = document.getElementById("bdIframe");
      if (bdIframe) {
        let mapFrame = bdIframe.contentWindow;
        this.$nextTick(() => {
          mapFrame.postMessage(
            {
              handlerType: "getScrollHeight",
              params: {
                height: data.height,
              },
            },
            "*"
          );
        });
      }
    },

 

(4)父頁面監聽滾動條距離頂部的距離方法,在項目最外層的index.vue中設置

getScroll (event) {
      this.$nextTick(() => {
        top.postMessage(
          {
            handlerType: "sendMassage",
            params: {
              height: event.target.scrollTop,
            },
          },
          "*"
        );
      });
      this.$refs.oIndexR.style.top = `${event.target.scrollTop}px`;
    },

    2、子頁面

 

    如果頁面高度有大於一頁高度的情況存在,需要先監聽主站的滾動條距離頂部的位置。
    點擊彈框,彈出彈框(設置點擊空白、按Esc鍵無法取消、有關閉按鈕的需要設置before-close關閉彈框),如果存在情況1,還需要設置margin-top或者top的值為主站的滾動條距離。
    根據彈框彈出或者關閉的visible的值,想主站發送當前的visible,做到同步開關。

    (1)子頁面el-dialog彈框HTML,messageBox彈框同理

<el-dialog
        :visible.sync="dialogTableVisible"
        center
        :modal-append-to-body="false"
        :close-on-press-escape="false"
        :close-on-click-modal="false"
      >
</el-dialog>

    (2)觸發關閉或者打開彈框的JS

      this.dialogTableVisible = false;//關閉false,打開true
      dialogPostMessage(false);
dialogPostMessage(isDialog) {
    top.postMessage(
        {
            handlerType: "changeDialog",
            params: {
                isDialog: isDialog,
            },
        },
        "*"
    );
}

   

    (3)附上需要監聽滾動條情況

data(){
    return{
       //當前滾動條距離頂部高度
       scrollHeight: 0
    }
}

created() {
    //監聽主頁面postmessage
    window.addEventListener(
      "message",
      (event) => {
        const { data } = event;
        this[data.handlerType] && this[data.handlerType](data.params);
      },
      false
    );
  },
beforeDestroy() {
    window.removeEventListener(
      "message",
      (event) => {
        const { data } = event;
        this[data.handlerType] && this[data.handlerType](data.params);
      },
      false
    );
},
methods:{
    //監聽滾動條高度
    getScrollHeight(data) {
      this.scrollHeight = data.height;
    },      
    showDialog(){      
     dialogPostMessage(true);
      this.dialogTableVisible = true;
      ......
      //預覽彈框位置調整
      let elDialogs = document.getElementsByClassName("el-dialog");
      elDialogs.forEach((elDialog) => {
          elDialog.style.marginTop = `${this.scrollHeight}px`;
      });
} }

 

 

 

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM