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';
                }
            };
        }
    }
}

 

解决这个问题耗费了好久,所以记录一下。希望能帮到遇到类似问题的同学,加油~

posted @ 2020-04-08 15:09  轻愁~  阅读(3737)  评论(4编辑  收藏  举报