同源跨Tab页互相通讯
第一种方法:Broadcast Channel API
介绍
BroadcastChannel 接口代理了一个命名频道,可以让指定 origin 下的任意 browsing context 来订阅它。它允许同源的不同浏览器窗口,Tab 页,frame 或者 iframe 下的不同文档之间相互通信。通过触发一个 message 事件,消息可以广播到所有监听了该频道的 BroadcastChannel 对象。
MDN BroadcastChannel API 文档
Can I use BroadcastChannel
使用方法
// 创建一个链接到【命名】频道的对象
let msgName = new BroadcastChannel('msgName')
//订阅消息处理
msgName.addEventListener('message',(MessageEvent) => {
console.log(`MessageEvent => %O `,MessageEvent);
})
//订阅消息错误处理
msgName.addEventListener('onmessageerror',(MessageEvent) => {
console.log(`MessageEvent => %O `,MessageEvent);
})
//发送消息
msgName.postMessage({ a: 'a' })
msgName.postMessage('字符串')
//关闭后,便于垃圾回收
msgName.close();
第二种方法:通过 window订阅storage事件
当localStorage在另一个文档的上下文中被修改时,Window接口的存储事件会触发。
抛砖引玉的示例
// 当前页
//事件缓存对象
let events = {}
// 订阅 同源的其他页面修改localStorage ,即当前页面修改localStorage不会触发storage事件
window.addEventListener('storage',function receiver(strorageEvent) {
var { key,newValue } = strorageEvent
if (newValue) {
// 触发事件
events[key]?.forEach?.(cb => cb(JSON.parse(newValue)))
}
});
// 订阅事件收集 函数
function subscribe(opt = { name: 'event',cb: (...rest) => consolelog(...rest) }) {
let { name,cb } = opt
if (!events[name]) {
events[name] = []
}
events[name].push(cb)
}
// 最后移除监听
// window.removeEventListener('storage', Receiver);
// 另一个同源页面
// 触发函数
function emitHandle(opt = { name: 'event',params: {} }) {
let { name,params } = opt
localStorage.setItem(name,JSON.stringify(params))
setTimeout(() => localStorage.removeItem(name),1000)
}
emitHandle({ name: 'event',params: { a: 'a' } })