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'; } }; } } }
解決這個問題耗費了好久,所以記錄一下。希望能幫到遇到類似問題的同學,加油~