实现方案1:location.hash传值

父页面:parent.html(所在域:www.parent.com)

子页面:child.html(所在域:www.child.com)

要实现父子页面双向的事件调用和传值,需要多加一个代理页面,主要用于子页面调用父页面的方法

代理页面:proxy.html(所在域:www.parent.com)必须与父页面在同域下

父页面调用子页面方法(即事件通过父页面发起,在子页面中执行):

父页面中直接设置iframe的src中的hash值

parent.html:

var frameurl = "http://www.child.com/child.html"
document.getElementById("frameId").src=frameurl+"#action="+actionName+"&data="+dataJSONStr;

子页面中设置定时器监听hash的变化,监听到后直接执行该方法

child.html:

var currentHash = location.hash;

setInterval(function(){

var hash = location.hash.substring(1);

if(currentHash!==hash){

  var action = ...;

  var data = ...;

  childFuncClass[action](data);

}

},1);

同样可以使用onhashchange事件监听到

子页面调用父页面方法(事件通过子页面发起,在父页面中执行)

在子页面child.html中添加一个iframe链接到上面所说的proxy.html,child.html中通过改变proxy.html的hash值,在proxy.html中监听hash变化事件,监听到以后直接调用parent.html中的方法(与父页面调用子页面方法一致)

proxy.html:

var currentHash = location.hash;

setInterval(function(){

var hash = location.hash.substring(1);

if(currentHash!==hash){

  var action = ...;

  var data = ...;

  window.parent.parent[action](data);

}

},1);

  

存在问题:

data长度限制,在chrome,ff,safari等浏览器中hash长度限制有50K以上,但是在ie下最多2000左右的限制。

回调函数的处理

通常情况下父页面在调用子页面的方法时会有一些回调函数(函数是在parent.html中编写和执行,但是需要child.html中的方法执行完成后再执行,有些情况下会需要child.html中执行的结果)

比如(通常情况下会做接口的封装):

parent.html:

var data={.....};

childFunc.func1(data,function(result){

//result即为child.html中执行func1后的结果值

});

  

child.html:

var func1 = function(data,callback){

//对data的一些操作

var result = ...;

callback&&callback(result);

}

  

如果出现这种情况的话parent.html中定义的匿名回调函数是不可能以字符串的形式传递到child.html中去的,并且也无法在child.html中再去执行父页面的回调函数

解决方法:

在接口封装的时候将回调函数保存下来,通过一个唯一的函数名传递到child.html中,child.html中的方法执行完成后将该函数名传递到proxy.html中执行该函数

以上面的func1为例

parent.html:

var eventIndex=0;
childFunc.func1 = function(data,callback){
if(//callback是function类型){
//此时window是parent页面的对象
window["myEvent"+eventIndex] = callback;
childIframe.hash="action=...&data=...&callback=myEvent"+eventIndex;
}
};

  

child.html:

var currentHash = location.hash;

setInterval(function(){

var hash = location.hash.substring(1);

if(currentHash!==hash){

  var action = ...;

  var data = ...;

   var callback=....;//应该是myEvent+index

  childFuncClass[action](data,function(result){
    proxyIfram.src.hash="action="+callback+"&data="+result;
  }); } },1);

  

proxy.html:

setInterval(function(){

  if(//hash changed){

    var callback  = //hash.callback
    var callbackData = //hash.callbackData
    window.parent.parent[callback](callbackData);
  } },1);

  

实现方案2:window.postMessage方法

由于方案1中对ie兼容性有问题(所有ie版本,包括ie11和edge都存在这个问题),方案2使用postMessage方法,该方法理论上对数据量没有限制(猜的),并且对ie可用

同样是使用iframe嵌入,

parent.html

var iframe = document.getElementById("childFrame").contentWindow;
var msg = {data:parentData,action:childFunc,callback:/*类似于上面的方法myEventIndex*/}
var childDomain = "http://www.child.com"
iframe.postMessage(msg,childDomain);
window.addEventListener("message",function(obj){
var data = obj.data;
var action = data.action;
var data = data.data;
parentFuncClass[action](data);
});

  

child.html

window.addEventListener("message",function(obj){
var data = obj.data;
var action = data.action;
var data = data.data;
var callback = data.callback;
childFuncClass[action](data,function(result){
var d = {action:callback,data:result};
var parentDomain="http://www.parent.com";
window.parent.postMessage(d,parentDomain);
});
});

  

真的是坑啊,把方案1中的坑都走过后才找到方案2的方法

Iframe父子窗口之间的跨域事件调用和传值的更多相关文章

  1. 父窗口和iframe子窗口之间相互传递参数和调用函数或方法

    1.父窗口向子窗口传递参数: 可以在url中添加参数:2.html?a=1&b=2&c=3 然后在子页面上可用js解析,提供一个函数: function getQueryStr(sAr ...

  2. JS方法在iframe父子窗口间的调用

    本文向大家简单介绍一下iframe父子窗口间JS方法调用,JavaScript 被数百万计的网页用来改进设计.验证表单.检测浏览器.创建cookies,以及更多的应用,希望本文介绍对你有所帮助. if ...

  3. 使用document.domain和iframe实现站内AJAX跨域

    站内AJAX跨域可以通过document.domain和iframe实现,比如www.css88.com.js.css88.com.css88.com这3个域名其实是3个不同的域,很多时候www.cs ...

  4. 使用JSONP进行跨域Ajax 调用

    JSONP 是啥 JSONP 全称是JSON with Padding. 当需要进行跨域Ajax 调用的时候, 需要用到JSONP 协议. 客户端 $.ajax({ url: 'http://xxx' ...

  5. iframe可通过postMessage解决跨域、跨窗口消息传递

    https://www.cnblogs.com/dorothyorsusie/p/6178599.html //iframe传参给父级页面 function give_info(){ console. ...

  6. iframe解决ajax主域和子域之间的跨域问题

    在某些应用场景下,需要在主域中,调用子域中的某个接口,如果直接在主域中向子域发ajax请求,会报跨域错误,可以用iframe来解决这种跨域问题.假如主域为www.baidu.com,子域为baike. ...

  7. iframe父子页面之间相互调用元素和函数

    <!doctype html> <html> <head> <meta http-equiv="Content-Type" content ...

  8. 用iframe设置代理解决ajax跨域请求问题

    面对ajax跨域请求的问题,想用代理的方式来解决这个跨域问题.在服务器端创建一个静态的代理页面,在客户端用iframe调用这个代理 今天在项目中需要做远程数据加载并渲染页面,直到开发阶段才意识到aja ...

  9. 如何设置iframe高度自适应,在跨域的情况下能做到吗?

    在页面上使用iframe来动态加载页面内容是网页开发中比较常见的方法.在父页面中给定一个不带滚动条的iframe,然后对属性src指定一个可加载的页面,这样当父页面被访问的时候,子页面可以被自动加载. ...

随机推荐

  1. unity(Exploder插件)研究

    哎 好久没写博客了 不是因为最近忙 而是比较懒 学的东西不深入 前段时间发现一个很好用的插件叫Exploder(是一个可以制作任何物体的爆炸效果) 好!我们开始我们的炸学校旅程!(O(∩_∩)O哈哈~ ...

  2. 团队作业8----第二次项目冲刺(beta阶段)5.24

    Day6-05.24 1.每日会议 会议内容: 1.组长林乔桦对昨日的工作进行了总结并且安排今日的任务. 2.阶段进入尾声,大家再一次集中对软件进行了优化讨论. 3.今天主要大家的工作重心放在异常的测 ...

  3. 201521123007《Java程序设计》第8周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 1. List中指定元素的删除(题目4-1) private static ...

  4. 201521123076 《Java程序设计》第6周学习总结

    1.本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖面 ...

  5. birt IE8 IE9 兼容问题

    我自己的应用,birt展示报表的时候,在firefox和IE下显示的样式: IE8下的: Firefox下的: 我的项目,应用birt部分的结构如下: 1, prototype.js ,查找下面这段代 ...

  6. Java通过链表实现栈

    class LinkedStack<T> { private Node top; private int size; /** * 初始化栈 */ public LinkedStack() ...

  7. nested exception is java.lang.IllegalArgumentException: Pointcut is not well-formed

    在用AOP 的时候出现了如下的错误, 警告: Exception encountered during context initialization - cancelling refresh atte ...

  8. 你的专属定制——JQuery自定义插件

        前  言 絮叨絮叨 jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架).jQuery设计的宗 ...

  9. 小知识点-ios跳过app store更新版本

    版本更新实现的思路 获取自身的版本号 获取AppStore的版本号 自身的版本号和AppStore的比较 弹窗提示所需数据的获取的方式 1.获取自身的版本号 2.AppStore的版本号 Wechat ...

  10. 深入理解计算机系统chapter8

    进程轮流使用处理器 父进程调用fork来创建一个新的子进程 回收子进程 waitpid/wait 非本地跳转: