Vue中使用iframe踩坑問題記錄 iframe+postMessage
使用iframe踩坑記錄 iframe+postMessage
需求:最近在寫一個博客的功能模塊,技術(shù)棧是單獨選擇的vuepress,完成后想要融合到一個vue工程里,考慮到后期維護(hù)的問題,就通過iframe將vuepress打包后的工程頁面引入到vue工程的一個頁面中,這樣iframe的父子級頁面之間也要進(jìn)行信息的傳遞,比如說傳遞iframe的子頁面的滾動高度給父頁面,然后撐開頁面高度。
1.iframe的初始高度問題
vue工程的一個組件,也就是iframe的父頁面,引入html;這里出現(xiàn)第一個坑,就是iframe的初始高度一定要設(shè)置,具體高度值可以預(yù)估一下iframe子頁面的高度,否則加載的時候就會出現(xiàn)閃屏的現(xiàn)象,體驗不好;如果iframe的子頁面高度是變化的,也就是說iframe要實現(xiàn)高度的自適應(yīng),接下往下看。。。
<div id="iframeBox"> ? ?<iframe id="iframeCon" src="./blog/index.html" width="100%" height="800px"></iframe> </div>
2.postMessage的實現(xiàn)
上面說到iframe要實現(xiàn)高度自適應(yīng),就需要借助postMessage來實現(xiàn)了,自己之前沒用過這個,找了很多資料說的感覺都不是很好,就自己直接寫了。
在iframe的子頁面中:函數(shù)寫在methods中,怎么去觸發(fā)getScrollHeight()這個函數(shù)看你具體的情況。注意一下,postMessage的源路徑,想要將信息傳遞到哪里。
為什么要寫定時器?如果頁面內(nèi)容超多,高度值很大,像我的就到了2W多px,需要等到頁面加載完成后才能獲取滾動高度,延時短了什么的是不能夠獲取準(zhǔn)確的高度值,會造成iframe的父級頁面出現(xiàn)雙滾動條,影響體驗。
最后,在頁面銷毀之前記得要清除定時器。個人感覺如果只有一個定時器,或者這個setTimeout不是為了實現(xiàn)setInterval的效果,也沒有其他的摻雜,是不用清除的。
beforeDestroy() { ? ?clearTimeout(this.timer); }, ? methods: { ? ? getScrollHeight() { ? ? ? ?this.timer = setTimeout(() => { ? ? ? ? ?et height = document.body.scrollHeight; ? ? ? ? ? window.parent.postMessage(height, "/"); ? ? ? ?}, 100); ? ? } }
在iframe的父級頁面中如何接收信息呢? 這里采用事件的監(jiān)聽,每次有子頁面?zhèn)鬟f信息的出現(xiàn),我們就獲取到傳遞信息中的高度值,然后設(shè)置給當(dāng)前頁面。同樣的記得移除監(jiān)聽。
created () { ? window.addEventListener('message', this.setHeightUpdate, false) }, destroyed () { ? window.removeEventListener('message', this.setHeightUpdate, false) }, methods: { ? setHeightUpdate () { ? ? let iframe = document.getElementById('iframeCon') ? ? iframe.height = event.data + 100 // 這里的event就是子頁面?zhèn)鬟^來的信息,可以打印到控制臺看 ? ? window.scrollTo(0, 0) // 為了回到頂部 ? } }
我遇到的就是這些了,雖然簡單,但是知識呀。。。
iframe使用postMessage傳值addEventListener未接收到卻收到webpackwarning問題
項目中使用到iframe,iframe跨域通信需要使用postMessage發(fā)送消息,addEventListener接收消息。
原先是獲取當(dāng)前窗口的數(shù)據(jù)發(fā)送過去。
const _iframe = document.getElementById('iframeViewer').contentWindow let _obj = res.data.data _obj.type = 'view' _obj.currentProcessInstanceId = row.id let Base64 = require('js-base64').Base64 _obj.processXml = Base64.decode(res.data.data.processXml) _iframe.postMessage(JSON.stringify(_obj), '*')
后來項目需求更新,需要將本來的窗口多加幾個菜單,可以進(jìn)行頁面切換。加了新的菜單之后就出現(xiàn)了問題,postMessage發(fā)送出了消息,控制臺打印出來addEventListener接收到的消息變成了webpack相關(guān)。
bug如下
問了大哥,發(fā)現(xiàn)問題可能是因為webpack自身會發(fā)送postMessage,需要區(qū)分接收到的是webpack發(fā)的還是自己發(fā)的。另外iframe是動態(tài)生成的,未加載好就發(fā)送postMessage,webpack會幫助發(fā)送。(大概是因為這個,具體的不清楚)
問題解決
所以一個是需要在iframe加載好之后發(fā)送postMessage,另一個是區(qū)分接收到的是webpack發(fā)的還是自己發(fā)的。
定義 const _iframe = document.getElementById('iframeViewer').contentWindow 獲取目標(biāo)窗口的窗口對象
定義iframeViewer = document.getElementById('iframeViewer') 獲取iframe元素對象
然后使用onload事件,window.οnlοad=function(){SomeJavaScriptCode};(onload事件會在頁面或圖像加載完成后立即發(fā)生)
const _iframe = document.getElementById('iframeViewer').contentWindow const iframeViewer = document.getElementById('iframeViewer') let _obj = res.data.data _obj.type = 'view' _obj.currentProcessInstanceId = this.currentProcessInstanceId let Base64 = require('js-base64').Base64 _obj.processXml = Base64.decode(res.data.data.processXml) iframeViewer.onload = () => { console.log('iframeViewer已加載') _iframe.postMessage(JSON.stringify(_obj), '*') }
這樣就確保了在iframe加載后再發(fā)送postMessage。
在addEventListener接收時,因為postMessage發(fā)送的時候傳了一個type,所以可以通過type來判斷發(fā)過來的是哪個event。
window.addEventListener("message", function(event) { _this.parentData = event.data; if (JSON.parse(_this.parentData).type === "view") { _this.frontTask = JSON.parse(_this.parentData).frontTask; _this.currentTask = JSON.parse(_this.parentData).currentTask; _this.backTask = JSON.parse(_this.parentData).backTask; _this.historyTask = JSON.parse(_this.parentData).historyTask; _this.processInstanceId = JSON.parse(_this.parentData).currentProcessInstanceId; _this.createNewDiagram(JSON.parse(_this.parentData).processXml); } })
寫好之后記得刷新頁面,不然就會像我一樣明明已經(jīng)改好了但還是看不到數(shù)據(jù)。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vuejs element table 表格添加行,修改,單獨刪除行,批量刪除行操作
這篇文章主要介紹了vuejs element table 表格添加行,修改,單獨刪除行,批量刪除行操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07vue-cli的build的文件夾下沒有dev-server.js文件配置mock數(shù)據(jù)的方法
這篇文章主要介紹了vue-cli的build的文件夾下沒有dev-server.js文件配置mock數(shù)據(jù)的方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-04-04vue2.0 + ele的循環(huán)表單及驗證字段方法
今天小編就為大家分享一篇vue2.0 + ele的循環(huán)表單及驗證字段方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09