介绍
在浏览器中为开发者提供了BroadcastChannelAPI,可以在不同标签页之间进行广播通信。其实等于是在浏览器的级别,针对当前同域的页面,做了一个跨页面窗口级别的EventEmitter。
如果你对实现EventEmitter感兴趣,可以点击笔者的这篇文章查看如何实现一个EventEmitter
大橙子认为它也是发布订阅模式的一种实践方式~~
实践
创建频道
通过创建一个BroadcastChannel实例来新建一个频道。
!!请注意!!需要在实例化的时候传入频道名称,所有监听这个频道的页面,都需要基于该名称来监听这个频道(因此建频道名称需要唯一)。
举个例子: 如果需要在电视上收看CCTV-1频道,那么在收看频道时,我们需要选择CCTV-1频道,并且这个名称肯定是唯一的,不可能有别的频道放着相同的节目也叫CCTV-1(有的话那叫李鬼(¬_¬))。
const bc = new BroadcastChannel('orange-channel');
你可以通过实例化后bc的name属性来获取名称:
console.log(bc.name) // orange-channel
从
EventEmitter的角度来看,其实等于是在全局注册了一个事件类型
监听及发送消息
监听消息和错误
在实例化完成BroadcastChannel后,就可以通过addEventListener监听message和messageerror事件,来获取消息和错误:
const bc = new BroadcastChannel('cctv1');
bc.addEventListener('message', (event) => {
console.log(event.data);
});
bc.addEventListener('messageerror', (event) => {
console.error(event);
});
从
EventEmitter的角度来看,通过浏览器的addEventListener实现了监听功能
发送消息
通过实例的postMessage方法,可以向所有监听该频道(name相同)的页面发送消息:
bc.postMessage('hello world!')
从
EventEmitter的角度来看,实现了触发事件功能
销毁频道
如果你已经不需要监听该频道,请一定要使用close方法!!
因为调用close后当前实例化资源会被浏览器回收。
bc.close()
从
EventEmitter的角度来看,实现了销毁监听功能。
测试页面
创建一个index.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BroadcastChannel Demo页面</title>
</head>
<body>
<div>
<span id="channel"></span><br>
<span id="message">当前频道暂无消息</span>
</div>
<button id="post">发送消息</button>
<button id="close">关闭频道</button>
<script>
const bc = new BroadcastChannel('orange-tv');
const tip = document.getElementById('channel');
tip.innerHTML = `当前你正在收听频道的是:${bc.name}`;
bc.addEventListener('message', (event) => {
document.getElementById('message').innerHTML = `当前频道的消息是:${event.data}`;
});
document.getElementById('post').addEventListener('click', () => {
bc.postMessage(`hello world, ${new Date().toLocaleString()}`);
});
document.getElementById('close').addEventListener('click', () => {
bc.close();
});
</script>
</body>
</html>
在webstorm中,你可以基于该页面打开3个标签页
在第一个打开的页面中,点击
发送消息按钮👇🏻
可以看到其余的两个页面中展示了刚刚点击按钮时的时间
如果在最后一个打开的页面中,点击了关闭频道按钮。再回到第一个打开的页面中,点击发送消息按钮
此时可以发现:第二个页面更新了时间,但是由于第三个页面已经关闭了频道,因此没有接收到最新的信息。
请注意!!
有些同学可能误认为将频道
close掉后,感觉上来说点击第一个页面的发送消息应该不能执行成功。事实上这个close和你关电视的感觉差不多,它只会将当前的监听关闭,并不会影响这个频道本身,如果其它页面有以同样name命名的频道还在,依旧可以发布消息。
当然这个浏览器API并不是所有浏览器都支持,使用前请先查阅兼容性!! 👉🏻caniuse.com/broadcastch…
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 11 天,点击查看活动详情