-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js.js
220 lines (188 loc) · 5.27 KB
/
index.js.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
(function() {
// 前缀
const STORAGE_PREFIX = 'shared-session-';
const CURRENT_TAB_URL = window.location.host + window.location.pathname;
const CHANNEL_NAME = 'session-storage-broadcast-15447';
//
const INIT_CHANNEL_NAME = 'session-storage-init-broadcast-324347';
const RECEIVE_CHANNEL_NAME = 'session-storage-receive-broadcast-324347';
// 进入页面
// 1、初始化sessionStorage,即:获取其他页面的sessionStorage
// 2、set和remove方法同步多个tab页
// 3、
// 接收广播
window.addEventListener("storage", function(event) {
/* sessionStorage相关专用频道,这个一个父频道 */
if (event.key == CHANNEL_NAME) {
let params = JSON.parse(event.newValue);
if(params.key == INIT_CHANNEL_NAME){
/* 请求sessionStorage初始化专用频道,这是子频道 */
// 1、获取当前tab页的sessionStorage
let results = _getCurrentTabItems();
// 2、广播所有的sessionStorage
_broadcast({type: 'broadcast', key: RECEIVE_CHANNEL_NAME, data: results, url: params.url})
}else if(params.key == RECEIVE_CHANNEL_NAME){
/* 接收sessionStorage初始化专用频道,这是子频道 */
// 初始化tab页的url==当前页
if(params.url == CURRENT_TAB_URL){
_receiveOtherTabItems(params.data);
}
// console.log(params.url == CURRENT_TAB_URL);
}else{
/* 同步sessionStorage item */
// 广播到其他存在的tab页面:a页面间接调用_broadcast(message),则b页面
try{
let valueParse = JSON.parse(event.newValue)
// console.log(valueParse)
if(valueParse.type == 'set'){
setItem(valueParse.key, valueParse.data, false);
}else if(valueParse.type == 'remove'){
removeItem(valueParse.key, false);
}
}catch(e){
console.error('同步sessionStorage转换错误:', event,e);
}
}
}
});
/**
* 向其他页面广播
* @param {Object} message {type: String, key: String, data: Object | null}
*/
const _broadcast = function(message) {
localStorage.setItem(CHANNEL_NAME, JSON.stringify(message));
};
// 存储到sessionStorage
const _storage = function(key) {
var args = [];
for (var i = 1; i < arguments.length; i += 1) {
args.push(arguments[i])
}
if (window && window.sessionStorage) {
return window.sessionStorage[key].apply(window.sessionStorage, args);
}
}
/**
* 获取当前tab页的所有sessionStorage
*/
const _getCurrentTabItems = function(){
let sessionKeys = Object.keys(sessionStorage)
let result = {}
for(let index in sessionKeys){
let key = sessionKeys[index]
if(key.indexOf(STORAGE_PREFIX) == 0){
result[key] = sessionStorage.getItem(key)
}
}
return result
}
/**
* @param {Object} items
* @fix 如果其他标签sessionStorage冲突,请根据sessionStorage的插入时间判断(保留最近的数据)
*/
const _receiveOtherTabItems = function(items){
// 设置到sessionStorage,但不广播
for(let key in items){
let sessionValue = sessionStorage.getItem(key)
if(!sessionValue){
// 当前tab没有sessionStorage item
sessionStorage.setItem(key, items[key])
continue
}
try{
let sessionValueParse= JSON.parse(sessionValue)
let itemParse = JSON.parse(items[key])
if(!sessionValueParse.time || sessionValueParse.time < itemParse.time){
sessionStorage.setItem(key, items[key])
}
}catch(e){
continue
}// end try catch
}// end for(...)
}
const _storageKey = function(key) {
return STORAGE_PREFIX + key;
}
const getItem = function(key, isBroadcast) {
let storeValue = _storage('getItem', _storageKey(key));
let result = JSON.parse(storeValue || '""')
if(isBroadcast){
// 向其他tab广播
_broadcast({
type: 'get',
key: key,
data: null,
// 防止连续两次相同的值时没有触发localstorage监听
mark: Date.now()+''+Math.random()
});
}
return result && result.data
};
/**
* 添加到sessionStorage
* @param {Object} key
* @param {Object} value
* @param {Boolean} isBroadcast 默认为true
*/
const setItem = function(key, value, isBroadcast) {
/*
存储后的数据结构
{
time: 存储时间戳,
data: 存储数据,
url: 当前存储url
}
*/
let params = {
time: Date.now(),
data: value,
url: CURRENT_TAB_URL
}
_storage('setItem', _storageKey(key), JSON.stringify(params));
if(isBroadcast || isBroadcast == undefined){
_broadcast({
type: 'set',
key: key,
data: value,
// 防止连续两次相同的值时没有触发localstorage监听
mark: Date.now()+''+Math.random()
});
}
};
/**
* 删除key
* @param {Object} key
* @param {Boolean} isBroadcast 默认为true
*/
const removeItem = function(key, isBroadcast) {
_storage('removeItem', _storageKey(key));
if(isBroadcast || isBroadcast == undefined){
_broadcast({
type: 'remove',
key: key,
data: null,
// 防止连续两次相同的值时没有触发localstorage监听
mark: Date.now()+''+Math.random()
});
}
}
const initItems = function(){
// TODO 获取当前items,也参与
_broadcast({
type: 'init',
key: INIT_CHANNEL_NAME,
data: null,
url: CURRENT_TAB_URL,
// 防止连续两次相同的值时没有触发localstorage监听
mark: Date.now()+''+Math.random()
});
}
//
let sessionPlus = {
'getItem': getItem,
'setItem': setItem,
'initItems': initItems,
'removeItem': removeItem,
}
window['sessionPlus'] = sessionPlus;
})()