iframe 子父页面互相通信

这篇博客详细介绍了如何在JavaScript中实现父子页面之间的消息传递。通过使用`postMessage`方法,可以实现从父页面向子页面以及从子页面向父页面发送数据。同时,展示了在接收到消息时的处理函数`handleMessage`的实现。示例代码涵盖了React组件中设置事件监听以及触发消息传递的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

知识点

1、父页面向子页面发送消息
  const idIframe = document.getElementById("idIframe").contentWindow
  const data = {data: 10000}
  idIframe.postMessage(data, '*');

2、子页面向父页面发送消息
  const data = {data: 10000}
  window.parent.postMessage(data , "*");
 
3、接收消息方法
  window.addEventListener('message', function (e) {
	// do something
  })

父页面

import React, { useState } from 'react';
import {Spin, Button} from 'antd'

export default class IframeIndex extends React.Component {
  refIframe = React.createRef()
  constructor() {
    super()
    this.state ={
      loading: true
    }
  }

  componentDidMount(){
    const idIframe = document.getElementById("idIframe")
    idIframe.onload = () => {
      this.setState({
        loading: false
      })
    }
    window.addEventListener("message", this.handleMessage)
  }
  /**
   * 监听子页面传过来的值的方法
   * @param {Object} event
   */
  handleMessage(event) {
    console.log(event, '监听子页面传过来的值的方法');
    // do something
  }

  /**
   * 向iframe传值的方法
   * @param {Object} data
   */
  sendMessage = () => {
    const idIframe = document.getElementById("idIframe").contentWindow
    const data = {data: 10000}
    idIframe.postMessage(data, '*');
  }

  render() {
    const { loading } = this.state

    return(
      <>
        <Spin spinning={loading}>
          <Button onClick={this.sendMessage}>向iframe传值的方法</Button>
          <iframe
            id={"idIframe"}
            ref={this.refIframe}
            frameBorder="0"
            src={'http://localhost:8000/iframe/child'}
            width={"100%"}
            height={"400px"}
          ></iframe>
        </Spin>
      </>
    )
  }
}

子页面

import React, { useState } from 'react';

import { Button } from 'antd';

export default class IframeIndex extends React.Component {
  constructor() {
    super();
    this.state = {};
  }

  componentDidMount() {
    // 监听postMessage 数据
    window.addEventListener('message', (e) => {
      console.log(e);
    });
  }

  /**
   * 向iframe传值的方法
   * @param {Object} data
   */
  sendMessage = () => {
    const idIframe = document.getElementById('idIframe').contentWindow;
    const data = { data: 10000 };
    idIframe.postMessage(data, '*');
  };

  render() {
    return (
      <>
        <div style={{ padding: '10px' }}>
          <Button size='small' onClick={() => this.postMessage()}>向父页面传值</Button>&nbsp;
        </div>
      </>
    );
  }
}
### 如何从父页面触发 iframe 页面的 `onload` 事件 在 HTMLJavaScript 中,可以通过操作 DOM 来实现父页面iframe 页面之间的交互。当需要从父页面触发 iframe 的 `onload` 事件时,可以利用以下几种方法。 #### 方法一:通过监听 iframe 的 load 事件 父页面可以直接绑定到 iframe 元素上的 `load` 事件来检测页面加载完成的时间点。以下是具体代码示例: ```javascript // 获取 iframe 元素 var iframeElement = document.getElementById('myIframe'); // 绑定 load 事件 iframeElement.onload = function () { console.log("iframe 页面已加载完毕"); }; ``` 这种方法适用于同源策略下父页面间的通信[^1]。如果跨域,则无法访问 iframe 内部的内容或执行其脚本。 --- #### 方法二:手动触发动态创建的 iframe 加载过程 有时可能需要动态设置 iframe 的 src 属性或者重新加载它以触发动态的 `onload` 事件。这种情况下可采用如下方式: ```javascript // 动态获取并重置 iframe 的 src 属性 var iframeElement = document.getElementById('myIframe'); iframeElement.src = iframeElement.src; // 或者直接刷新 iframe 页面 iframeElement.contentWindow.location.reload(); ``` 上述代码会强制让 iframe 进入新的加载流程,并自动触发它的 `onload` 事件处理程序[^2]。 --- #### 方法三:调用页面内的函数模拟 onload 行为 假如希望更灵活地控制何时触发某些逻辑而不仅仅是依赖默认的 `onload` 时间点,可以在页面定义好特定初始化函数之后由父页面主动去调用这个函数作为替代方案之一: ```javascript // 假设这是存在于 childPage.js 文件里的一个公开可用功能 function initializeChildFrame() { ... } // 父页面中尝试调用该初始化器 document.getElementById('myIframe').contentWindow.initializeChildFrame(); ``` 注意这里同样受限于浏览器的安全模型即所谓的“Same-Origin Policy”,只有两者处于相同协议、端口以及主机名的情况下才允许互相访问彼此的对象属性和方法[^3]。 --- ### 总结 综上所述,在满足同源条件下,最常用的方式是从父窗口监控 iframe 的 load 事件;而对于特殊需求则考虑调整资源地址促使重新渲染或是直接介入目标文档内部结构进行自定义化管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值