【react和iframe的数据通信】
业务场景,前端一个弹框中,使用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,结束