观察者设计模式又称订阅发布模式,在JS中我们习惯叫做广播模式,当多个对象监听一个通道时,只要发布者向该通道发布命令,订阅者都可以收到该命令,然后执行响应的逻辑。今天我们要实现的就是通过观察者设计模式,实现iframe之间的通信。

一、top对象

一般的JS书里都会在讲框架集的时候讲top,这会让人误解,认为top对象只是代表框架集,其实top的含义应该是说浏览器直接包含的那一个页面对象,也就是说如果你有一个页面被其他页面以iframe的方式包含了,无论包含的层级是什么,都可以用top访问最外层的哪一个页面,因为这个页面被浏览器直接包含,这个事情的意义在于如果多个页面被同时加载,他们之间需要通信,就完全可以在最外层的页面设置一个通信对象,其他页面都通过这个对象进行通信(需要说明的是,如果要这么干,需要将他们部署在服务器上进行测试,仅仅在文件系统上测试,可能因为跨域而测试失败)。

二、搭建广播站

(function(top,undefined){
var observerAble={};
var radioStation={};
radioStation.subscription=function(channel,obj){
if(!observerAble[channel]){
var array=new Array();
array.push(obj);
observerAble[channel]=array;
}else{
observerAble[channel].push(obj);
}
};
radioStation.broadcast=function(channel,data){
for(var item in observerAble[channel]){
observerAble[channel][item].update(data);
}
};
top.radioStation=radioStation;
}(top))

  我们将广播站放到top对象中,后面的所有iframe都可以从top中获得该对象。我们只要建立通道,一旦广播站对该通道发布命令,我们就可以从update方法中获取命令参数。

三、测试

1、radioStation.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="jquery-3.2.1.js"></script>
<!-- 引入广播站,创建广播站对象-->
<script type="text/javascript" src="RadioStation.js"></script>
</head>
<body>
<button id="broadcast">broadcast</button>
<iframe src="radioStation2.html" frameborder="0"></iframe>
<div id="topdiv1"></div>
<div id="topdiv2"></div>
<script>
function sayHello(){
this.update=function(data){
$("#topdiv1").text(data);
}
}
function sayGoodBye(){
this.update=function(data){
$("#topdiv2").text(data);
}
}
var sayhello=new sayHello();
var saygoodbye=new sayGoodBye();
//订阅
radioStation.subscription("hello",sayhello);
radioStation.subscription("hello",saygoodbye);
//广播
$("#broadcast").click(function(){
radioStation.broadcast("hello",'hello radioStation');
}); </script>
</body>
</html>

  2、radioStation2.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src="jquery-3.2.1.js"></script>
</head>
<body>
我是一个iframe
<div id="iframediv1"></div>
<div id="iframediv2"></div>
<script>
function sayHello(){
this.update=function(data){
$("#iframediv1").text(data);
}
}
function sayGoodBye(){
this.update=function(data){
$("#iframediv2").text(data);
}
}
var sayhello=new sayHello();
var saygoodbye=new sayGoodBye();
//订阅,从最外层的窗口对象top中获取radioStation对象
top.radioStation.subscription("hello",sayhello);
top.radioStation.subscription("hello",saygoodbye);
</script>
</body>
</html>

  四、效果

JS观察者设计模式:实现iframe之间快捷通信的更多相关文章

  1. 父页面和iframe之间的通信(操作和传值问题)

    一.jq实现iframe父页面与子页面传值与方法调用 1.值操作 (1)父页面获取子页面的值 $('iframe的id').contents().find(子页面的id).text(); (2)子页面 ...

  2. 《Head First设计模式》批注系列(一)——观察者设计模式

    最近在读<Head First设计模式>一书,此系列会引用源书内容,但文章内容会更加直接,以及加入一些自己的理解. 观察者模式(有时又被称为模型-视图(View)模式.源-收听者(List ...

  3. window之间、iframe之间的JS通信

    一.Window之间JS通信 在开发项目过程中,由于要引入第三方在线编辑器,所以需要另外一个窗口(window),而且要求打开的window要与原来的窗口进行js通信,那么如何实现呢? 1.在原窗口创 ...

  4. iframe之间通信问题及iframe自适应高度问题

    下面本人来谈谈iframe之间通信问题及iframe自适应高度问题. 1. iframe通信 分为:同域通信 和 跨域通信.所谓同域通信是指 http://localhost/demo/iframe/ ...

  5. js组件之间的通信

    应用场景: 1.在刷微博的时候,滑到某个头像上,会出现一张usercard(用户名片), 微博列表区有这个usercard, 推荐列表也有这个usercard,评论区也有. 2.在网上购物时,购物车安 ...

  6. Vue.js组件之同级之间的通信

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. javascript 中contentWindow和 frames和iframe之间通信

    iframe父子兄弟之间通过jquery传值(contentWindow && parent),iframe的调用包括以下几个方面:(调用包含html dom,js全局变量,js方法) ...

  8. JS备忘--子父页面获取元素属性、显示时间,iframe之间互相调用函数

    //页面加载完成后执行 $(function () { getHW();}); //当用户改变浏览器大小改变时触发 $(window).resize(function () { setHW(); }) ...

  9. Cocos中的观察者设计模式与通知机制

    观察者(Observer)模式也叫发布/订阅(Publish/Subscribe)模式,是 MVC( 模型-视图-控制器)模式的重要组成部分.天气一直是英国人喜欢讨论的话题,而最近几年天气的变化也成为 ...

随机推荐

  1. toJSON() 方法,将 Date 对象转换为字符串,并格式化为 JSON 数据格式。

    JavaScript toJSON() 方法 定义和用法 toJSON() 方法可以将 Date 对象转换为字符串,并格式化为 JSON 数据格式. JSON 数据用同样的格式就像x ISO-8601 ...

  2. Power-Aware GateSim Debug

    For PAG debug, the following steps may be useful. 1. Get correct netlists from PD which contain powe ...

  3. C++ 打印XPS文档

    CoInitializeEx(, COINIT_MULTITHREADED); IXpsOMObjectFactory *xpsFactory; HRESULT hr = CoCreateInstan ...

  4. 新手 Redis 配置笔记(windows),附下载地址

    1.关于安装文件的选择 安装的时候应该下载免安装版,安装版虽然一路下一步就可以了,但是,当要修改配置文件的时候,特别痛苦,搜了两个小时,居然没有找到如何用命令修改配置文件,开放远程连接.所以对于第一次 ...

  5. python中继承、定制类

    2.4python中继承 继承中不要忘了调用super().__init__ def __init__(self,args) super(subclass,self).__init___(args) ...

  6. ASP.NET MVC3.0下载功能实现

    C#代码: #region 下载文件 /// <summary> /// 下载文件 /// </summary> /// <param name="url&qu ...

  7. NOIP2002-字串变换【双向BFS】

    NOIP2002-字串变换 Description 已知有两个字串A,BA,B及一组字串变换的规则(至多66个规则): A_1A1​ ->B_1B1​ A_2A2​ -> B_2B2​ 规 ...

  8. NDK undefined reference to 'rand'

    NDK 编译 结果报错undefined reference to 'rand' 最怪异的是armeabi-v7a armeabi的情况下有问题 但是arm64-v8a编译正常,用网上说的添加头文件s ...

  9. 连接Access数据库

    web.config添加配置 <connectionStrings> <add name="connStr" connectionString="Pro ...

  10. 2018-5 - 凉经 - 乐糖游戏 - PHP 开发实习生

    收到面试通知当天因为学校出事要求我明天必须回去,所以就买当晚的火车票,然后跟公司说学校有事明天没法去面试了,公司人事比较好给我安排到当天下午面试.公司规模不是很大,但位置好下了地铁到,可能因为招的是实 ...