業務場景,前端一個彈框中,使用iframe嵌入了一個子項目,子項目中的操作完成之后,需要關閉彈框;
關系:父組件react 頁面 ,子組件 嵌入的頁面
實現方案:
1.window全局定義一個事件xxx,代碼塊里面寫關閉的方法;子項目中window.xxx
2.通過判斷子項目中的某個dom元素值的變化判斷子項目的交互操作狀態,例如 input的value值0未完成和1已完成,可以關閉彈窗,
在父組件寫一個監聽事件,監聽dom元素變化,為1時關閉彈窗
3.通過postMessage contentWindow.postMessage 進行通信 (iframe向react通信 react向iframe傳消息)
postMessage iframe向react通信
實現步驟
1、子組件頁面
觸發事件代碼塊: window.parent && window.parent.postMessage('傳的消息xxx','*');
2.react頁面設置監聽
在componentDidMount事件里面
componentDidMount() { let self = this; //為了避免作用域及緩存 window.mesFromIframe = function (event) { if (event != undefined) { console.log('react組件,來自iframe的關閉彈窗的消息:', event.data); //操作的代碼塊 比如隱藏modal self.setState({ xxx:false }) } } //監聽message事件 window.addEventListener("message", mesFromIframe false); }
contentWindow.postMessage react向iframe傳消息
1.父組件
觸發事件代碼塊:
this.setState({ xxx: true }, () => { setTimeout(() => { const iframeObj = document.getElementById('mesIframe');
iframeObj.contentWindow.postMessage(123, '*'); }, 0);})
mesIframe iframe定義的id名字
<iframe style={{ width: '100%', height: '100%' }} id='mesIframe' allowFullScreen={true} scrolling={'no'} src="http://192.168.xxx:81/#/login" />
注意:需要等彈窗頁面dom完全加載完 才能get到dom元素 所以在變量設置完之后 加了一個延時器操作代碼
2.iframe頁面
//回調函數 function mesIframe ( event ) { console.log( 'iframe,來自react的消息:', event.data ); } //監聽message事件 window.addEventListener("message", mesIframe, false);
Ok,結束