引言

随着Web技术的发展,涌出了越来越多的复杂的应用。诸多Web应用逐渐向增强用户体验方向发展。在诸如付款、在线聊天等场景中,有时需要多页面进行数据通信。以前的实现方法有cookie、服务器中转、Flash插件等方法,而HTML5提供了新的LocalStorage API,能够更为便捷的实现跨页面通信,且相比以前的技术有容量大、效率高、无需插件等优点。

“What”能实现什么

LocalStorage API被IE8+及Firefox、Chrome、Safari等主流浏览器所支持。利用localStorage能够实现数据的存储,而通过监控数据的写入,页面可以获得其它页面想要传达的信息。

在“在线聊天”功能中,服务器与客户端的数据通信需要占用大量的带宽和服务器计算时间,而如果一个浏览器同时打开了多个窗口更是雪上加霜。作为一个绿色环保的程序员,相对于堆服务器,我们应该立足于解决带宽与计算量的浪费,而通过跨页面的协同合作,我们可以实现多个页面之间可以共享一条数据通道,同时节省了服务器和客户端的消耗。

其它的诸如微博等应用的“换肤”功能,如果能够实现打开的多个窗口同时更换皮肤,势必能够提高用户的体验。

“Where”用在何处

上面已经提及了两处应用场景,实际上任何Web应用都应该考虑多窗口的情形。用于在窗口之间切换时,如何实现无障碍的应用体验?产品经理总是抱怨打开了多个窗口怎么就不能实现联动?在一个窗口登录了其它窗口怎么就非得刷新才能使用一些功能?这些统统可以通过跨页面通信解决。

“How”怎么实现

HTML5 LocalStorage API中包含了"storage"事件。通过监听window对象的storage事件,可以在其它页面窗口调用localStorage的存储方法时,得到通知。为了进行跨页面通信事件与普通存储事件的区分,我封装了一个channel库,可以通过命名空间进行数据的监听。

channel库代码如下:

 1 /**
 2  * Channel.js: Browser support for multipage communication
 3  *
 4  * @author Kyriosli
 5  */
 6 var channel = function(entry) {
 7     var listeners = {};
 8
 9     if (/MSIE 8/.test(navigator.userAgent)) {
10         window.attachEvent('storage', function() {
11             // TODO: ie8 support
12         });
13     } else {
14         window.addEventListener('storage', function(e) {
15             if (e.newValue !== null && /^channel\.(.+)/.test(e.key)) {
16                 broadcast(RegExp.$1, e.newValue);
17             }
18         });
19     }
20
21     function broadcast(channelName, str) {
22         if (channelName in listeners) {
23             var value = JSON.parse(str);
24             for ( var i = 0, arr = listeners[channelName], L = arr.length; i < L; i++) {
25                 try {
26                     arr[i](value);
27                 } catch (e) {
28                     console.error(e.stack);
29                 }
30             }
31         }
32     }
33
34     return {
35         /**
36          * 发布数据到其它页面
37          *
38          * @param name
39          *            命名空间名称
40          * @param value
41          *            要发布的数据
42          * @returns this
43          */
44         post : function(name, value) {
45             entry["channel." + name] = JSON.stringify(value);
46             setTimeout(function() {
47                 entry.removeItem("channel." + name);
48             }, 0);
49             return this;
50         },
51         /**
52          * 注册监听器
53          *
54          * @param name
55          *            要监听的命名空间
56          * @param callback
57          *            回调函数
58          * @returns this
59          */
60         on : function(name, callback) {
61             if (name in listeners) {
62                 listeners[name].push(callback);
63             } else {
64                 listeners[name] = [ callback ];
65             }
66             return this;
67         },
68         /**
69          * 取消监听器
70          *
71          * @param name
72          *            要取消监听的命名空间
73          * @param callback
74          *            回调函数,如果为空,则取消所有监听函数
75          * @returns this
76          */
77         off : function(name, callback) {
78             var arr = listeners[name];
79             if (arr) {
80                 if (!callback) {
81                     delete listeners[name];
82                 } else {
83                     var i = arr.length;
84                     while (i--) {
85                         if (arr[i] === callback) {
86                             arr.splice(i, 1);
87                         }
88                     }
89                 }
90             }
91             return this;
92         }
93     };
94 }(localStorage);

channel有3个函数:post,on,off。当窗口A调用了on函数,窗口B调用post函数时,窗口A就会收到事件。如:

// 窗口A
channel.on('abcde', function(data) {console.log(data);
});// 窗口B
channel.post('abcde', "Hello world");

那么窗口A将输出'Hello world'。

其它

IE8/9的兼容

IE8/9的storage事件与主流浏览器有所不同,主要有两个地方:

  1. IE8/9的storage事件不携带key和newValue等属性
  2. IE8/9的storage事件触发在localStorage的值真正改变之前

所以要支持IE8/9,必须在事件触发后,设置超时,并扫描检测所有localStorage中存储的key,手动检测其值是否发生改变。

转载于:https://www.cnblogs.com/kyrios/archive/2013/04/16/multipage-communication-channel.html

利用HTML5 LocalStorage实现跨页面通信channel相关推荐

  1. [转]html5: postMessage解决跨域和跨页面通信的问题

    [转]html5: postMessage解决跨域和跨页面通信的问题 参考文章: (1)[转]html5: postMessage解决跨域和跨页面通信的问题 (2)https://www.cnblog ...

  2. 面试官:前端跨页面通信,你知道哪些方法?

    引言 在浏览器中,我们可以同时打开多个Tab页,每个Tab页可以粗略理解为一个"独立"的运行环境,即使是全局对象也不会在多个Tab间共享.然而有些时候,我们希望能在这些" ...

  3. java按钮触发另一个页面_前端跨页面通信,你知道哪些方法?

    戳蓝字「前端技术优选」关注我们哦! 引言 在浏览器中,我们可以同时打开多个Tab页,每个Tab页可以粗略理解为一个"独立"的运行环境,即使是全局对象也不会在多个Tab间共享.然而有 ...

  4. 两个html页面之间通讯,面试官:前端跨页面通信,你知道哪些方法?

    引言 在浏览器中,我们可以同时打开多个Tab页,每个Tab页可以粗略理解为一个"独立"的运行环境,即使是全局对象也不会在多个Tab间共享.然而有些时候,我们希望能在这些" ...

  5. 微信小程序跨页面通信解决思路

    宏观上,微信小程序是由一个个 Page 组成的.有时候我们会遇到一些业务存在耦合的 Page,一个 Page 里某个状态改变后,相关 Page 的状态需要进行更新.而在小程序里,每个 Page 都是一 ...

  6. 利用iframe实现ajax 跨域通信的解决方案

    在漫长的前端开发旅途上,无可避免的会接触到ajax,而且一般情况下都是用在同一域下的ajax请求:但是如果请求是发生在不同的域下,请求就无法执行,并且会抛出异常提示不允许跨域请求,目前我没有找到明确的 ...

  7. html5 通信方式,(原生js页面通信)关于html5的PostMessage的用法总结

    大家都知道,网页之间传递数据可以使用ajax请求来完成,今天我总结下我学习的postMessage是如何完成跨页面请求数据的呢?首先,postMessage是html5新增的一个解决跨域的一个方法.那 ...

  8. js 原生跨页面通信_DOM操作是跨线程的你知道吗?

    在JS世界里面浏览器有两个重要的功能,分为渲染引擎和JS引擎.渲染引擎专门负责渲染Html和css的,JS引擎是专门用来执行JS的.这两个引擎是在不同的线程里面,它们都自己做着自己的事情,互不打扰. ...

  9. JavaScript 利用location对象实现跨页面传参

    需求简述: 两个页面login.html和homepage.html,在login页输入用户名,点击登录会跳转到主页,主页拿到login页输入的用户名 实现思路: 1. 跳转:修改location.h ...

最新文章

  1. 给Sqlite数据库设置密码
  2. 超级详细的解决方法 (CentOS7) :永久修改 mysql read-only 问题 could not retrieve transation read-only status server
  3. 介绍一个统计键盘和鼠标输入情况的工具软件
  4. git的入门摸索和入门研究
  5. nssl1196-摘果子【树形依赖背包,dp】
  6. datetime的文本时间处理
  7. mac 黑窗口连接mysql_mac系统下mysql环境变量设置及远程连接
  8. 【Proteus仿真8086】简单IO接口实验——无条件传输和查询方式
  9. oracle递归树查询
  10. tomcat日志中文乱码问题
  11. mysql 联合主键 null_MySQL联合主键的索引使用
  12. 记大数据hbase集群天坑
  13. 计算机电源出现叉叉是怎么回事,解决Win7下笔记本右下角电池打红叉提示请考虑更换电池问题...
  14. OPC DA与OPC UA的区别
  15. html在线聊天界面模板,一款带气泡对话框的HTML5聊天应用界面模板
  16. python作业02
  17. 按键消抖+点亮led灯
  18. 【大数据面试题】(一)Hadoop 相关面试题总结
  19. 通俗的角度理解遍历性定理 (从大数定理,中心极限定理再到遍历性定理)
  20. oracle中top命令详解,top命令-leonwang202-ChinaUnix博客

热门文章

  1. 删除oracle的注册,oracle数据库账号删除oracle收集系统统计信息
  2. mooc java_中国大学moocJava程序设计答案大全
  3. 理解 webpack 热更新
  4. 如何在Javascript中创建范围
  5. mysql视图什么时候用_Mysql为什么要使用视图?
  6. html表单的课后心得体会,web前端学习心得体会范文
  7. c语言表达式amp;amp;,C语言中的运算符及其优先级
  8. c访问mysql数据库_C语言访问MySQL数据库的方法
  9. 即时系统和非即时系统的区别?_家庭装修,能不能让热水来得快一点——即时热水系统...
  10. CSS去除按钮激活的高亮边框(Button的点击出现黑色外边框的取消)