forked from biqing/MessengerJS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
messenger.js
139 lines (127 loc) · 4.67 KB
/
messenger.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/**
* __ ___
* / |/ /___ _____ _____ ___ ____ ____ _ ___ _____
* / /|_/ // _ \ / ___// ___// _ \ / __ \ / __ `// _ \ / ___/
* / / / // __/(__ )(__ )/ __// / / // /_/ // __// /
* /_/ /_/ \___//____//____/ \___//_/ /_/ \__, / \___//_/
* /____/
*
* @description MessengerJS, a common cross-document communicate solution.
* @author biqing kwok
* @version 2.0
* @license release under MIT license
*/
window.Messenger = (function(){
// 消息前缀, 建议使用自己的项目名, 避免多项目之间的冲突
// !注意 消息前缀应使用字符串类型
var prefix = "[PROJECT_NAME]",
supportPostMessage = 'postMessage' in window;
// Target 类, 消息对象
function Target(target, name, prefix){
var errMsg = '';
if(arguments.length < 2){
errMsg = 'target error - target and name are both required';
} else if (typeof target != 'object'){
errMsg = 'target error - target itself must be window object';
} else if (typeof name != 'string'){
errMsg = 'target error - target name must be string type';
}
if(errMsg){
throw new Error(errMsg);
}
this.target = target;
this.name = name;
this.prefix = prefix;
}
// 往 target 发送消息, 出于安全考虑, 发送消息会带上前缀
if ( supportPostMessage ){
// IE8+ 以及现代浏览器支持
Target.prototype.send = function(msg){
this.target.postMessage(this.prefix + '|' + this.name + '__Messenger__' + msg, '*');
};
} else {
// 兼容IE 6/7
Target.prototype.send = function(msg){
var targetFunc = window.navigator[this.prefix + this.name];
if ( typeof targetFunc == 'function' ) {
targetFunc(this.prefix + msg, window);
} else {
throw new Error("target callback function is not defined");
}
};
}
// 信使类
// 创建Messenger实例时指定, 必须指定Messenger的名字, (可选)指定项目名, 以避免Mashup类应用中的冲突
// !注意: 父子页面中projectName必须保持一致, 否则无法匹配
function Messenger(messengerName, projectName){
this.targets = {};
this.name = messengerName;
this.listenFunc = [];
this.prefix = projectName || prefix;
this.initListen();
}
// 添加一个消息对象
Messenger.prototype.addTarget = function(target, name){
var targetObj = new Target(target, name, this.prefix);
this.targets[name] = targetObj;
};
// 初始化消息监听
Messenger.prototype.initListen = function(){
var self = this;
var generalCallback = function(msg){
if(typeof msg == 'object' && msg.data){
msg = msg.data;
}
var msgPairs = msg.split('__Messenger__');
var msg = msgPairs[1];
var pairs = msgPairs[0].split('|');
var prefix = pairs[0];
var name = pairs[1];
for(var i = 0; i < self.listenFunc.length; i++){
if (prefix + name === self.prefix + self.name) {
self.listenFunc[i](msg);
}
}
};
if ( supportPostMessage ){
if ( 'addEventListener' in document ) {
window.addEventListener('message', generalCallback, false);
} else if ( 'attachEvent' in document ) {
window.attachEvent('onmessage', generalCallback);
}
} else {
// 兼容IE 6/7
window.navigator[this.prefix + this.name] = generalCallback;
}
};
// 监听消息
Messenger.prototype.listen = function(callback){
var i = 0;
var len = this.listenFunc.length;
var cbIsExist = false;
for (; i < len; i++) {
if (this.listenFunc[i] == callback) {
cbIsExist = true;
break;
}
}
if (!cbIsExist) {
this.listenFunc.push(callback);
}
};
// 注销监听
Messenger.prototype.clear = function(){
this.listenFunc = [];
};
// 广播消息
Messenger.prototype.send = function(msg){
var targets = this.targets,
target;
for(target in targets){
if(targets.hasOwnProperty(target)){
targets[target].send(msg);
}
}
};
return Messenger;
})();