MetaBase使用iframe內嵌到Vue頁面樣式優化


Matebase是一個開源,易上手的BI工具,這里不做太多介紹了。

官網地址:https://www.metabase.com/

 

解決問題描述:

使用iframe內嵌Metabase公開鏈接之后,頁面樣式不美觀:

1、Metabase默認有背景色,背景的高度不會因為開啟了滾動條就適應高度。

2、如果不成為Metabase的付費用戶,所使用的的公開連接左下角會有Powerd by Metabse。(違反Metabase開源約定)

解決方案描述:

此方案能夠生效,前提是iframe里面的鏈接不能跨域,跨域將無法獲取iframe內的元素高度。

1、在頁面完成渲染之后,獲取iframe內的元素高度,動態為iframe設置樣式高度。

2、監聽瀏覽器窗口的尺寸變化,動態更新iframe的高度設置(如果單純變化寬度,此時iframe不會自動增高,沒找到寬度跟高度的對應關系,有興趣你可以自己研究一下)

3、監聽左側菜單導航欄的寬度變化:本項目中,左側菜單導航欄可以收縮,最小寬度為54px,最大210px。需要根據實際進行調整

 

使用Matebase構建完成自己的儀表盤之后,點擊分享並編輯按鈕:

 

 

 

 

 

 

如果什么都不做呢,Matebase顯示樣式會很難看。如下圖:

 

 

 

接下來介紹一下樣式優化方案:

1、iframe樣式設置如下:

<iframe
    id="bdIframe"
    ref="myIframe"
    src="http://localhost/matebase/public/dashboard/6f47b37b-0f86-4dad-822d-d69440ffe5e2"

    frameborder="0"
    style="width:100%;height: 100%;"
    allowtransparency
    scrolling="no"

></iframe>

2、iframe高度自適應:

let _this = null;

export default {
    name: 'DashboardEditor',
    data() {
    },
    created() {
        _this = this;
    },
    mounted() {
        _this = this;
        this.adaptIframeHeight();
        window.onresize = () => {
            const oIframe = document.getElementById('bdIframe');
            try {
                let iDoc = oIframe.contentDocument || oIframe.document || oIframe.contentWindow;
                let cHeight = Math.max(iDoc.body.clientHeight, iDoc.documentElement.clientHeight);
                let sHeight = Math.max(iDoc.body.scrollHeight, iDoc.documentElement.scrollHeight);
                console.info("cHeight=" + cHeight + ", sHeight=" + sHeight);
                let height = Math.max(cHeight, sHeight);
                oIframe.style.height = height + 'px';
                // 隱藏 Power By MetaBase
                // let footerDiv = iDoc.getElementsByClassName("EmbedFrame-footer");
                // if (footerDiv[0] !== undefined) {
                //     footerDiv[0].style.display = 'none';
                // }
            } catch (e) {
                console.error("窗口大小變化時,iframe高度自適應異常!" + e);
                oIframe.style.height = '1000px';
            }
        };
        try {
            const erd = elementResizeDetectorMaker();
            let sidebarWidth = null;
            // 監聽左側導航欄的寬度變化
            erd.listenTo(document.getElementsByClassName("sidebar-container"), (element) => {
                sidebarWidth = element.offsetWidth;
                _this.$nextTick(() => {
                    let addHeight = 210;
                    // 導航欄收縮最小的時候,加大iframe的高度
                    if (sidebarWidth === 54) {
                        const oIframe = _this.$refs.myIframe;
                        if (undefined !== oIframe) {
                            console.info(oIframe);
                            let oldHeight = oIframe.style.height;
                            if (undefined !== oldHeight && oldHeight !== '100%') {
                                oIframe.style.height = (Number(oldHeight.replace("px", ""))) + addHeight + 'px';
                            }
                        }
                    }
                    // 導航欄伸展到最大時,減少iframe的高度
                    if (sidebarWidth === 210) {
                        const oIframe = _this.$refs.myIframe;
                        if (undefined !== oIframe) {
                            console.info(oIframe);
                            let oldHeight = oIframe.style.height;
                            if (undefined !== oldHeight && oldHeight !== '100%') {
                                oIframe.style.height = (Number(oldHeight.replace("px", ""))) - addHeight + 'px';
                            }
                        }
                    }
                })
            })
        } catch (e) {
            console.error("監聽左側導航欄寬度變化異常!" + e);
        }
    },
    methods: {
        adaptIframeHeight() {
            const oIframe = document.getElementById('bdIframe');
            oIframe.onload = () => {
                try { // iframe高度自適應
                    let iDoc = oIframe.contentDocument || oIframe.document || oIframe.contentWindow;
                    let cHeight = Math.max(iDoc.body.clientHeight, iDoc.documentElement.clientHeight);
                    let sHeight = Math.max(iDoc.body.scrollHeight, iDoc.documentElement.scrollHeight);
                    let height = Math.max(cHeight, sHeight);
                    oIframe.style.height = height + 'px';
                    // 隱藏 Power By MetaBase
                    // let footerDiv = iDoc.getElementsByClassName("EmbedFrame-footer");
                    // if (footerDiv[0] !== undefined) {
                    //     footerDiv[0].style.display = 'none';
                    // }
                } catch (e) {
                    console.error("iframe高度自適應異常!" + e);
                    oIframe.style.height = '1000px';
                }
            };
        }
    }
}

 

解決這個問題耗費了好久,所以記錄一下。希望能幫到遇到類似問題的同學,加油~


免責聲明!

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



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