注意:以下 FrameName 为 iframe name 属性的值

父子页面同域

方法调用

父页面调用子页面方法:FrameName.childMethod(); // childMethod 为子页面中定义的方法

子页面调用父页面方法:parent.parentMethod(); // parentMethod 为父页面中定义的方法

DOM 访问

父页面访问子页面DOM:FrameName.document.getElementById("childDom"); //childDom 为子页面标签 id

子页面访问父页面DOM:parent.document.getElementById("parentDom"); // parentDom 为父页面标签 id

注意事项

要确保在 iframe 加载完成后再进行操作,如果 iframe 还未加载完成就开始调用里面的方法或变量,会产生错误。判断 iframe 是否加载完成有两种方法:

  1. iframe 上用 onload 事件

    1
    2
    3
    4
    5
    6
    onloadFrame = function(){
    let msg = "参数";
    FrameName.childMethod(msg);
    }

    <iframe src="child.html" name="FrameName" onload="onloadFrame()" ></iframe>
  2. 用 FrameName.document.readyState==”complete” 来判断

    1
    2
    3
    if(FrameName.document.readyState == "complete") {
    FrameName.childMethod();
    }

父子页面跨域通信

方案一「优选」

window.postMessage() 方法可以安全地实现跨源通信

MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage

发送数据

父页面向子页面传递数据
1
2
3
4
5
6
FrameName.postMessage('hello,你好吗', '*');
或者
FrameIdDom.contentWindow.postMessage('hello,你好吗', '*'); //FrameIdDom 为 iframe id 属性的值

// vue 页面
this.$refs.iframe.contentWindow.postMessage({ type: 'print', data: "打印" }, '*');;
子页面向父页面传递数据
1
parent.postMessage('good,我很好', '*');

接收数据

1
2
3
4
5
6
7
8
9
window.addEventListener('message',function(event){
document.getElementById('id').innerText = event.data;
});

// 接收数据
window.addEventListener("message", function(event){
console.log(event.data)
// { type: 'print', data: "打印" }
});

方案二

父页面向子页面传递数据

利用 location 对象的 hash 值,通过它传递通信数据。在父页面设置 iframe 的 src 后面加个 #数据,然后在子页面中通过location.hash方式定时获取数据。示例:

  1. 父页面中根据情况修改 iframe src #后面的数据
  2. 在子页面中通过 setInterval 方法设置定时器,监听 location.href 或者location.hash的变化,然后根据这个数据进行相应的逻辑处理

子页面向父页面传递数据

利用一个代理 iframe「和父页面同域」,把它嵌入到子页面中。子页面把数据传递给代理 iframe「通过跨域父页面向子页面传递数据方式」,然后由于代理的 iframe 和父页面是同域的,所以使用 window.top 或者 window.parent.parent 获取父页面的引用